diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:08 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:08 -0400 |
commit | 57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1 (patch) | |
tree | 9a62d8e2f2370e8d6b01f469c67e70e787515b32 /drivers/hwmon/adm1026.c | |
parent | 7dbafe021ba360bf25674a7e290d3e4a5c953981 (diff) |
hwmon: (adm1026) Convert to a new-style i2c driver
The new-style adm1026 driver implements the optional detect() callback
to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/adm1026.c')
-rw-r--r-- | drivers/hwmon/adm1026.c | 109 |
1 files changed, 44 insertions, 65 deletions
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 904c6ce9d83f..7fe2441fc845 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -259,7 +259,6 @@ struct pwm_data { | |||
259 | }; | 259 | }; |
260 | 260 | ||
261 | struct adm1026_data { | 261 | struct adm1026_data { |
262 | struct i2c_client client; | ||
263 | struct device *hwmon_dev; | 262 | struct device *hwmon_dev; |
264 | 263 | ||
265 | struct mutex update_lock; | 264 | struct mutex update_lock; |
@@ -293,10 +292,11 @@ struct adm1026_data { | |||
293 | u8 config3; /* Register value */ | 292 | u8 config3; /* Register value */ |
294 | }; | 293 | }; |
295 | 294 | ||
296 | static int adm1026_attach_adapter(struct i2c_adapter *adapter); | 295 | static int adm1026_probe(struct i2c_client *client, |
297 | static int adm1026_detect(struct i2c_adapter *adapter, int address, | 296 | const struct i2c_device_id *id); |
298 | int kind); | 297 | static int adm1026_detect(struct i2c_client *client, int kind, |
299 | static int adm1026_detach_client(struct i2c_client *client); | 298 | struct i2c_board_info *info); |
299 | static int adm1026_remove(struct i2c_client *client); | ||
300 | static int adm1026_read_value(struct i2c_client *client, u8 reg); | 300 | static int adm1026_read_value(struct i2c_client *client, u8 reg); |
301 | static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); | 301 | static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); |
302 | static void adm1026_print_gpio(struct i2c_client *client); | 302 | static void adm1026_print_gpio(struct i2c_client *client); |
@@ -305,22 +305,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev); | |||
305 | static void adm1026_init_client(struct i2c_client *client); | 305 | static void adm1026_init_client(struct i2c_client *client); |
306 | 306 | ||
307 | 307 | ||
308 | static const struct i2c_device_id adm1026_id[] = { | ||
309 | { "adm1026", adm1026 }, | ||
310 | { } | ||
311 | }; | ||
312 | MODULE_DEVICE_TABLE(i2c, adm1026_id); | ||
313 | |||
308 | static struct i2c_driver adm1026_driver = { | 314 | static struct i2c_driver adm1026_driver = { |
315 | .class = I2C_CLASS_HWMON, | ||
309 | .driver = { | 316 | .driver = { |
310 | .name = "adm1026", | 317 | .name = "adm1026", |
311 | }, | 318 | }, |
312 | .attach_adapter = adm1026_attach_adapter, | 319 | .probe = adm1026_probe, |
313 | .detach_client = adm1026_detach_client, | 320 | .remove = adm1026_remove, |
321 | .id_table = adm1026_id, | ||
322 | .detect = adm1026_detect, | ||
323 | .address_data = &addr_data, | ||
314 | }; | 324 | }; |
315 | 325 | ||
316 | static int adm1026_attach_adapter(struct i2c_adapter *adapter) | ||
317 | { | ||
318 | if (!(adapter->class & I2C_CLASS_HWMON)) { | ||
319 | return 0; | ||
320 | } | ||
321 | return i2c_probe(adapter, &addr_data, adm1026_detect); | ||
322 | } | ||
323 | |||
324 | static int adm1026_read_value(struct i2c_client *client, u8 reg) | 326 | static int adm1026_read_value(struct i2c_client *client, u8 reg) |
325 | { | 327 | { |
326 | int res; | 328 | int res; |
@@ -1647,48 +1649,32 @@ static const struct attribute_group adm1026_group_in8_9 = { | |||
1647 | .attrs = adm1026_attributes_in8_9, | 1649 | .attrs = adm1026_attributes_in8_9, |
1648 | }; | 1650 | }; |
1649 | 1651 | ||
1650 | static int adm1026_detect(struct i2c_adapter *adapter, int address, | 1652 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1651 | int kind) | 1653 | static int adm1026_detect(struct i2c_client *client, int kind, |
1654 | struct i2c_board_info *info) | ||
1652 | { | 1655 | { |
1656 | struct i2c_adapter *adapter = client->adapter; | ||
1657 | int address = client->addr; | ||
1653 | int company, verstep; | 1658 | int company, verstep; |
1654 | struct i2c_client *client; | ||
1655 | struct adm1026_data *data; | ||
1656 | int err = 0; | ||
1657 | const char *type_name = ""; | ||
1658 | 1659 | ||
1659 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1660 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1660 | /* We need to be able to do byte I/O */ | 1661 | /* We need to be able to do byte I/O */ |
1661 | goto exit; | 1662 | return -ENODEV; |
1662 | }; | 1663 | }; |
1663 | 1664 | ||
1664 | /* OK. For now, we presume we have a valid client. We now create the | ||
1665 | client structure, even though we cannot fill it completely yet. | ||
1666 | But it allows us to access adm1026_{read,write}_value. */ | ||
1667 | |||
1668 | if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { | ||
1669 | err = -ENOMEM; | ||
1670 | goto exit; | ||
1671 | } | ||
1672 | |||
1673 | client = &data->client; | ||
1674 | i2c_set_clientdata(client, data); | ||
1675 | client->addr = address; | ||
1676 | client->adapter = adapter; | ||
1677 | client->driver = &adm1026_driver; | ||
1678 | |||
1679 | /* Now, we do the remaining detection. */ | 1665 | /* Now, we do the remaining detection. */ |
1680 | 1666 | ||
1681 | company = adm1026_read_value(client, ADM1026_REG_COMPANY); | 1667 | company = adm1026_read_value(client, ADM1026_REG_COMPANY); |
1682 | verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); | 1668 | verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); |
1683 | 1669 | ||
1684 | dev_dbg(&client->dev, "Detecting device at %d,0x%02x with" | 1670 | dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" |
1685 | " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", | 1671 | " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", |
1686 | i2c_adapter_id(client->adapter), client->addr, | 1672 | i2c_adapter_id(client->adapter), client->addr, |
1687 | company, verstep); | 1673 | company, verstep); |
1688 | 1674 | ||
1689 | /* If auto-detecting, Determine the chip type. */ | 1675 | /* If auto-detecting, Determine the chip type. */ |
1690 | if (kind <= 0) { | 1676 | if (kind <= 0) { |
1691 | dev_dbg(&client->dev, "Autodetecting device at %d,0x%02x " | 1677 | dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x " |
1692 | "...\n", i2c_adapter_id(adapter), address); | 1678 | "...\n", i2c_adapter_id(adapter), address); |
1693 | if (company == ADM1026_COMPANY_ANALOG_DEV | 1679 | if (company == ADM1026_COMPANY_ANALOG_DEV |
1694 | && verstep == ADM1026_VERSTEP_ADM1026) { | 1680 | && verstep == ADM1026_VERSTEP_ADM1026) { |
@@ -1704,7 +1690,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1704 | verstep); | 1690 | verstep); |
1705 | kind = any_chip; | 1691 | kind = any_chip; |
1706 | } else { | 1692 | } else { |
1707 | dev_dbg(&client->dev, ": Autodetection " | 1693 | dev_dbg(&adapter->dev, ": Autodetection " |
1708 | "failed\n"); | 1694 | "failed\n"); |
1709 | /* Not an ADM1026 ... */ | 1695 | /* Not an ADM1026 ... */ |
1710 | if (kind == 0) { /* User used force=x,y */ | 1696 | if (kind == 0) { /* User used force=x,y */ |
@@ -1713,33 +1699,29 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1713 | "force_adm1026.\n", | 1699 | "force_adm1026.\n", |
1714 | i2c_adapter_id(adapter), address); | 1700 | i2c_adapter_id(adapter), address); |
1715 | } | 1701 | } |
1716 | goto exitfree; | 1702 | return -ENODEV; |
1717 | } | 1703 | } |
1718 | } | 1704 | } |
1705 | strlcpy(info->type, "adm1026", I2C_NAME_SIZE); | ||
1719 | 1706 | ||
1720 | /* Fill in the chip specific driver values */ | 1707 | return 0; |
1721 | switch (kind) { | 1708 | } |
1722 | case any_chip : | 1709 | |
1723 | type_name = "adm1026"; | 1710 | static int adm1026_probe(struct i2c_client *client, |
1724 | break; | 1711 | const struct i2c_device_id *id) |
1725 | case adm1026 : | 1712 | { |
1726 | type_name = "adm1026"; | 1713 | struct adm1026_data *data; |
1727 | break; | 1714 | int err; |
1728 | default : | 1715 | |
1729 | dev_err(&adapter->dev, ": Internal error, invalid " | 1716 | data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL); |
1730 | "kind (%d)!\n", kind); | 1717 | if (!data) { |
1731 | err = -EFAULT; | 1718 | err = -ENOMEM; |
1732 | goto exitfree; | 1719 | goto exit; |
1733 | } | 1720 | } |
1734 | strlcpy(client->name, type_name, I2C_NAME_SIZE); | ||
1735 | 1721 | ||
1736 | /* Fill in the remaining client fields */ | 1722 | i2c_set_clientdata(client, data); |
1737 | mutex_init(&data->update_lock); | 1723 | mutex_init(&data->update_lock); |
1738 | 1724 | ||
1739 | /* Tell the I2C layer a new client has arrived */ | ||
1740 | if ((err = i2c_attach_client(client))) | ||
1741 | goto exitfree; | ||
1742 | |||
1743 | /* Set the VRM version */ | 1725 | /* Set the VRM version */ |
1744 | data->vrm = vid_which_vrm(); | 1726 | data->vrm = vid_which_vrm(); |
1745 | 1727 | ||
@@ -1748,7 +1730,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1748 | 1730 | ||
1749 | /* Register sysfs hooks */ | 1731 | /* Register sysfs hooks */ |
1750 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) | 1732 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) |
1751 | goto exitdetach; | 1733 | goto exitfree; |
1752 | if (data->config1 & CFG1_AIN8_9) | 1734 | if (data->config1 & CFG1_AIN8_9) |
1753 | err = sysfs_create_group(&client->dev.kobj, | 1735 | err = sysfs_create_group(&client->dev.kobj, |
1754 | &adm1026_group_in8_9); | 1736 | &adm1026_group_in8_9); |
@@ -1773,15 +1755,13 @@ exitremove: | |||
1773 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); | 1755 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); |
1774 | else | 1756 | else |
1775 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); | 1757 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); |
1776 | exitdetach: | ||
1777 | i2c_detach_client(client); | ||
1778 | exitfree: | 1758 | exitfree: |
1779 | kfree(data); | 1759 | kfree(data); |
1780 | exit: | 1760 | exit: |
1781 | return err; | 1761 | return err; |
1782 | } | 1762 | } |
1783 | 1763 | ||
1784 | static int adm1026_detach_client(struct i2c_client *client) | 1764 | static int adm1026_remove(struct i2c_client *client) |
1785 | { | 1765 | { |
1786 | struct adm1026_data *data = i2c_get_clientdata(client); | 1766 | struct adm1026_data *data = i2c_get_clientdata(client); |
1787 | hwmon_device_unregister(data->hwmon_dev); | 1767 | hwmon_device_unregister(data->hwmon_dev); |
@@ -1790,7 +1770,6 @@ static int adm1026_detach_client(struct i2c_client *client) | |||
1790 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); | 1770 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); |
1791 | else | 1771 | else |
1792 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); | 1772 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); |
1793 | i2c_detach_client(client); | ||
1794 | kfree(data); | 1773 | kfree(data); |
1795 | return 0; | 1774 | return 0; |
1796 | } | 1775 | } |