/*
C
* File: fusb30x_driver.* Company: Fairchild Semiconductor
*
* Created on September 2, 2015, therefore AM
*/
Standard Linux includes/* */
# include
# include
# include
# include
# include
# include
# include
# include
/* Driver - specific includes */
# include "fusb30x_global. H"//Driver - specific structures/types
# include "platform_helpers. H"//I2C R/W, GPIO, misc, etc
# include ".. "///core/core. H GetDeviceTypeCStatus
# ifdef FSC_DEBUG
# include "DFS. H"
# endif//FSC_DEBUG
# include "fusb30x_driver. H"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Driver functions provides
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Static int __init fusb30x_init (void)
{
Pr_debug (" FUSB % s - Start driver initialization... \ n ", __func__);
Return i2c_add_driver (& fusb30x_driver);
}
The static void __exit fusb30x_exit (void)
{
I2c_del_driver (& fusb30x_driver);
Pr_debug (" FUSB % s - the Driver does... \ n ", __func__);
}
Static int fusb302_i2c_resume (struct device * dev)
{
Struct fusb30x_chip * chip;
Struct i2c_client * client=to_i2c_client (dev);
If (client) {
Chip=i2c_get_clientdata (the client);
If (chip)
The up (& chip -> suspend_lock);
}
return 0;
}
Static int fusb302_i2c_suspend (struct device * dev)
{
Struct fusb30x_chip * chip;
Struct i2c_client * client=to_i2c_client (dev);
If (client) {
Chip=i2c_get_clientdata (the client);
If (chip)
Down (& chip -> suspend_lock);
}
return 0;
}
Static int fusb30x_probe (struct i2c_client * client,
Const struct i2c_device_id * id)
{
int ret=0;
Struct fusb30x_chip * chip;
Struct i2c_adapter * adapter;
if (! The client)
{
Pr_err (" FUSB % s - Error: Client structure is NULL! \ n ", __func__);
The return - EINVAL;
}
Dev_info (& client -> dev, "% s \ n", __func__);
/* Make sure the probe was called on a compatible device */
if (! Of_match_device (fusb30x_dt_match, & client -> dev))
{
Dev_err (& client -> dev, "FUSB % s - Error: Device tree mismatch! \ n ", __func__);
The return - EINVAL;
}
Pr_debug (" FUSB % s - Device tree matched! \ n ", __func__);
/* the Allocate space for our chip structure (devm_ * is managed by the device) */
Chip=devm_kzalloc (& client -> dev, sizeof (* chip), GFP_KERNEL);
if (! Chip)
{
Dev_err (& client -> dev, "FUSB % s - Error: Unable to the allocate memory for g_chip! \ n ", __func__);
The return - ENOMEM;
}
Chip -> client=client;//Assign our client handle to our chip
Fusb30x_SetChip (chip);//Set our global chip 's address to the newly allocated memory
Pr_debug (" FUSB % s - Chip structure is set! Chip: % p... G_chip: % p \ n ", __func__, chip, fusb30x_GetChip ());
/* the Initialize the chip lock */
Mutex_init (& chip -> lock);
/* the Initialize the chip 's data members */
Fusb_InitChipData ();
Pr_debug (" FUSB % s - Chip struct data the initialized! \ n ", __func__);
/* Verify that the system has our required I2C/SMBUS functionality (see
Adapter=to_i2c_adapter (client -> dev. The parent).
If (i2c_check_functionality (adapter, FUSB30X_I2C_SMBUS_BLOCK_REQUIRED_FUNC))
{
Chip -> use_i2c_blocks=true;
}
The else
{
//If the platform doesn 't support block reads, try with block writes and single reads (works with eg. RPi)
//NOTE: It is likely that this may result in non - standard behaviors, but will, be "close enough" to work for most things
Dev_warn (& client -> dev, "FUSB % s - Warning: the I2C/SMBus block the read/write functionality not supported, checking single - read mode... \ n ", __func__);
if (! I2c_check_functionality (adapter, FUSB30X_I2C_SMBUS_REQUIRED_FUNC))
{
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull