Skip to content

Commit

Permalink
i2c: Add support for device alias names
Browse files Browse the repository at this point in the history
Based on earlier work by Jon Smirl and Jochen Friedrich.

This patch allows new-style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). At this
point, the old i2c driver binding scheme (driver_name/type) is still
supported.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Jochen Friedrich <jochen@scram.de>
Cc: Jon Smirl <jonsmirl@gmail.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
  • Loading branch information
Jean Delvare authored and Jean Delvare committed Apr 29, 2008
1 parent ee56d97 commit d2653e9
Show file tree
Hide file tree
Showing 43 changed files with 146 additions and 54 deletions.
3 changes: 2 additions & 1 deletion Documentation/i2c/writing-clients
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ I2C device drivers using this binding model work just like any other
kind of driver in Linux: they provide a probe() method to bind to
those devices, and a remove() method to unbind.

static int foo_probe(struct i2c_client *client);
static int foo_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int foo_remove(struct i2c_client *client);

Remember that the i2c_driver does not create those client handles. The
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpio/pca953x.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
gc->owner = THIS_MODULE;
}

static int __devinit pca953x_probe(struct i2c_client *client)
static int __devinit pca953x_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpio/pcf857x.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value)

/*-------------------------------------------------------------------------*/

static int pcf857x_probe(struct i2c_client *client)
static int pcf857x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf857x_platform_data *pdata;
struct pcf857x *gpio;
Expand Down
8 changes: 5 additions & 3 deletions drivers/hwmon/f75375s.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ struct f75375_data {
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
static int f75375_probe(struct i2c_client *client);
static int f75375_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);

static struct i2c_driver f75375_legacy_driver = {
Expand Down Expand Up @@ -628,7 +629,8 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,

}

static int f75375_probe(struct i2c_client *client)
static int f75375_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct f75375_data *data = i2c_get_clientdata(client);
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
Expand Down Expand Up @@ -748,7 +750,7 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(client)))
goto exit_free;

if ((err = f75375_probe(client)) < 0)
if ((err = f75375_probe(client, NULL)) < 0)
goto exit_detach;

return 0;
Expand Down
3 changes: 2 additions & 1 deletion drivers/i2c/chips/ds1682.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eeprom_attr = {
/*
* Called when a ds1682 device is matched with this driver
*/
static int ds1682_probe(struct i2c_client *client)
static int ds1682_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;

Expand Down
3 changes: 2 additions & 1 deletion drivers/i2c/chips/menelaus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)

static struct i2c_driver menelaus_i2c_driver;

static int menelaus_probe(struct i2c_client *client)
static int menelaus_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct menelaus_chip *menelaus;
int rev = 0, val;
Expand Down
3 changes: 2 additions & 1 deletion drivers/i2c/chips/tps65010.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,8 @@ static int __exit tps65010_remove(struct i2c_client *client)
return 0;
}

static int tps65010_probe(struct i2c_client *client)
static int tps65010_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps65010 *tps;
int status;
Expand Down
3 changes: 2 additions & 1 deletion drivers/i2c/chips/tsl2550.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2c_client *client)
*/

static struct i2c_driver tsl2550_driver;
static int __devinit tsl2550_probe(struct i2c_client *client)
static int __devinit tsl2550_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct tsl2550_data *data;
Expand Down
51 changes: 42 additions & 9 deletions drivers/i2c/i2c-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr);

/* ------------------------------------------------------------------------- */

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
id++;
}
return NULL;
}

static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
Expand All @@ -59,6 +70,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
if (!is_newstyle_driver(driver))
return 0;

/* match on an id table if there is one */
if (driver->id_table)
return i2c_match_id(driver->id_table, client) != NULL;

/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
Expand All @@ -73,11 +88,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
struct i2c_client *client = to_i2c_client(dev);

/* by definition, legacy drivers can't hotplug */
if (dev->driver || !client->driver_name)
if (dev->driver)
return 0;

if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
return -ENOMEM;
if (client->driver_name[0]) {
if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
return -ENOMEM;
} else {
if (add_uevent_var(env, "MODALIAS=%s%s",
I2C_MODULE_PREFIX, client->name))
return -ENOMEM;
}
dev_dbg(dev, "uevent\n");
return 0;
}
Expand All @@ -90,13 +111,19 @@ static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
const struct i2c_device_id *id;
int status;

if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
status = driver->probe(client);

if (driver->id_table)
id = i2c_match_id(driver->id_table, client);
else
id = NULL;
status = driver->probe(client, id);
if (status)
client->driver = NULL;
return status;
Expand Down Expand Up @@ -179,9 +206,9 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att
static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return client->driver_name
return client->driver_name[0]
? sprintf(buf, "%s\n", client->driver_name)
: 0;
: sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}

static struct device_attribute i2c_dev_attrs[] = {
Expand Down Expand Up @@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_client *client)
EXPORT_SYMBOL_GPL(i2c_unregister_device);


static int dummy_nop(struct i2c_client *client)
static int dummy_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
return 0;
}

static int dummy_remove(struct i2c_client *client)
{
return 0;
}

static struct i2c_driver dummy_driver = {
.driver.name = "dummy",
.probe = dummy_nop,
.remove = dummy_nop,
.probe = dummy_probe,
.remove = dummy_remove,
};

/**
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/cs5345.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)

/* ----------------------------------------------------------------------- */

static int cs5345_probe(struct i2c_client *client)
static int cs5345_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/cs53l32a.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/

static int cs53l32a_probe(struct i2c_client *client)
static int cs53l32a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;

Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/cx25840/cx25840-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,

/* ----------------------------------------------------------------------- */

static int cx25840_probe(struct i2c_client *client)
static int cx25840_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct cx25840_state *state;
u32 id;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/m52790.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ static int m52790_command(struct i2c_client *client, unsigned int cmd,

/* i2c implementation */

static int m52790_probe(struct i2c_client *client)
static int m52790_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct m52790_state *state;

Expand Down
2 changes: 1 addition & 1 deletion drivers/media/video/msp3400-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ static int msp_resume(struct i2c_client *client)

/* ----------------------------------------------------------------------- */

static int msp_probe(struct i2c_client *client)
static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct msp_state *state;
int (*thread_func)(void *data) = NULL;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/mt9m001.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,8 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
soc_camera_video_stop(&mt9m001->icd);
}

static int mt9m001_probe(struct i2c_client *client)
static int mt9m001_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct mt9m001 *mt9m001;
struct soc_camera_device *icd;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/mt9v022.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,8 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
soc_camera_video_stop(&mt9v022->icd);
}

static int mt9v022_probe(struct i2c_client *client)
static int mt9v022_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct mt9v022 *mt9v022;
struct soc_camera_device *icd;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/saa7115.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,8 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar

/* ----------------------------------------------------------------------- */

static int saa7115_probe(struct i2c_client *client)
static int saa7115_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa711x_state *state;
int i;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/saa7127.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,8 @@ static int saa7127_command(struct i2c_client *client,

/* ----------------------------------------------------------------------- */

static int saa7127_probe(struct i2c_client *client)
static int saa7127_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa7127_state *state;
struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/saa717x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,8 @@ static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
/* i2c implementation */

/* ----------------------------------------------------------------------- */
static int saa717x_probe(struct i2c_client *client)
static int saa717x_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct saa717x_state *decoder;
u8 id = 0;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/tcm825x.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,8 @@ static struct v4l2_int_device tcm825x_int_device = {
},
};

static int tcm825x_probe(struct i2c_client *client)
static int tcm825x_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct tcm825x_sensor *sensor = &tcm825x;
int rval;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/tlv320aic23b.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ static int tlv320aic23b_command(struct i2c_client *client,
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/

static int tlv320aic23b_probe(struct i2c_client *client)
static int tlv320aic23b_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tlv320aic23b_state *state;

Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/tuner-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,8 @@ static void tuner_lookup(struct i2c_adapter *adap,
/* During client attach, set_type is called by adapter's attach_inform callback.
set_type must then be completed by tuner_probe.
*/
static int tuner_probe(struct i2c_client *client)
static int tuner_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tuner *t;
struct tuner *radio;
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/video/tvaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,7 @@ static struct CHIPDESC chiplist[] = {
/* ---------------------------------------------------------------------- */
/* i2c registration */

static int chip_probe(struct i2c_client *client)
static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct CHIPSTATE *chip;
struct CHIPDESC *desc;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/upd64031a.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)

/* i2c implementation */

static int upd64031a_probe(struct i2c_client *client)
static int upd64031a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct upd64031a_state *state;
int i;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/upd64083.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)

/* i2c implementation */

static int upd64083_probe(struct i2c_client *client)
static int upd64083_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct upd64083_state *state;
int i;
Expand Down
5 changes: 3 additions & 2 deletions drivers/media/video/v4l2-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
/* Helper function for I2C legacy drivers */

int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
const char *name, int (*probe)(struct i2c_client *))
const char *name,
int (*probe)(struct i2c_client *, const struct i2c_device_id *))
{
struct i2c_client *client;
int err;
Expand All @@ -724,7 +725,7 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
client->driver = driver;
strlcpy(client->name, name, sizeof(client->name));

err = probe(client);
err = probe(client, NULL);
if (err == 0) {
i2c_attach_client(client);
} else {
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/vp27smpx.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/

static int vp27smpx_probe(struct i2c_client *client)
static int vp27smpx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct vp27smpx_state *state;

Expand Down
Loading

0 comments on commit d2653e9

Please sign in to comment.