diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-06-15 12:01:51 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-06-15 12:01:51 -0400 |
commit | 351ca3e31197929535418f5affc761cd9fb07428 (patch) | |
tree | e8602108fa3402081f2fd4210dee62c141ed7fab /drivers/macintosh/windfarm_lm75_sensor.c | |
parent | 1b9f37d488f09342610b29ac1c8e734e540932ab (diff) |
windfarm: Convert to new-style i2c drivers
The legacy i2c binding model is going away soon, so convert the
macintosh windfarm drivers to the new model or they will break.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Tested-by: Johannes Berg <johannes@sipsolutions.net>
Tested-by: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/macintosh/windfarm_lm75_sensor.c')
-rw-r--r-- | drivers/macintosh/windfarm_lm75_sensor.c | 129 |
1 files changed, 73 insertions, 56 deletions
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index b92b959fe16e..529886c7a826 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
@@ -37,34 +37,22 @@ | |||
37 | struct wf_lm75_sensor { | 37 | struct wf_lm75_sensor { |
38 | int ds1775 : 1; | 38 | int ds1775 : 1; |
39 | int inited : 1; | 39 | int inited : 1; |
40 | struct i2c_client i2c; | 40 | struct i2c_client *i2c; |
41 | struct wf_sensor sens; | 41 | struct wf_sensor sens; |
42 | }; | 42 | }; |
43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) | 43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) |
44 | #define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c) | ||
45 | |||
46 | static int wf_lm75_attach(struct i2c_adapter *adapter); | ||
47 | static int wf_lm75_detach(struct i2c_client *client); | ||
48 | |||
49 | static struct i2c_driver wf_lm75_driver = { | ||
50 | .driver = { | ||
51 | .name = "wf_lm75", | ||
52 | }, | ||
53 | .attach_adapter = wf_lm75_attach, | ||
54 | .detach_client = wf_lm75_detach, | ||
55 | }; | ||
56 | 44 | ||
57 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | 45 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) |
58 | { | 46 | { |
59 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 47 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
60 | s32 data; | 48 | s32 data; |
61 | 49 | ||
62 | if (lm->i2c.adapter == NULL) | 50 | if (lm->i2c == NULL) |
63 | return -ENODEV; | 51 | return -ENODEV; |
64 | 52 | ||
65 | /* Init chip if necessary */ | 53 | /* Init chip if necessary */ |
66 | if (!lm->inited) { | 54 | if (!lm->inited) { |
67 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); | 55 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1); |
68 | 56 | ||
69 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", | 57 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", |
70 | sr->name, cfg); | 58 | sr->name, cfg); |
@@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
73 | * the firmware for now | 61 | * the firmware for now |
74 | */ | 62 | */ |
75 | cfg_new = cfg & ~0x01; | 63 | cfg_new = cfg & ~0x01; |
76 | i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); | 64 | i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new); |
77 | lm->inited = 1; | 65 | lm->inited = 1; |
78 | 66 | ||
79 | /* If we just powered it up, let's wait 200 ms */ | 67 | /* If we just powered it up, let's wait 200 ms */ |
@@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
81 | } | 69 | } |
82 | 70 | ||
83 | /* Read temperature register */ | 71 | /* Read temperature register */ |
84 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); | 72 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0)); |
85 | data <<= 8; | 73 | data <<= 8; |
86 | *value = data; | 74 | *value = data; |
87 | 75 | ||
@@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr) | |||
92 | { | 80 | { |
93 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 81 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
94 | 82 | ||
95 | /* check if client is registered and detach from i2c */ | ||
96 | if (lm->i2c.adapter) { | ||
97 | i2c_detach_client(&lm->i2c); | ||
98 | lm->i2c.adapter = NULL; | ||
99 | } | ||
100 | |||
101 | kfree(lm); | 83 | kfree(lm); |
102 | } | 84 | } |
103 | 85 | ||
@@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = { | |||
107 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
108 | }; | 90 | }; |
109 | 91 | ||
110 | static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | 92 | static int wf_lm75_probe(struct i2c_client *client, |
111 | u8 addr, int ds1775, | 93 | const struct i2c_device_id *id) |
112 | const char *loc) | ||
113 | { | 94 | { |
114 | struct wf_lm75_sensor *lm; | 95 | struct wf_lm75_sensor *lm; |
115 | int rc; | 96 | int rc; |
116 | 97 | ||
117 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
118 | ds1775 ? "ds1775" : "lm75", addr); | ||
119 | |||
120 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); | 98 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); |
121 | if (lm == NULL) | 99 | if (lm == NULL) |
122 | return NULL; | 100 | return -ENODEV; |
101 | |||
102 | lm->inited = 0; | ||
103 | lm->ds1775 = id->driver_data; | ||
104 | lm->i2c = client; | ||
105 | lm->sens.name = client->dev.platform_data; | ||
106 | lm->sens.ops = &wf_lm75_ops; | ||
107 | i2c_set_clientdata(client, lm); | ||
108 | |||
109 | rc = wf_register_sensor(&lm->sens); | ||
110 | if (rc) { | ||
111 | i2c_set_clientdata(client, NULL); | ||
112 | kfree(lm); | ||
113 | } | ||
114 | |||
115 | return rc; | ||
116 | } | ||
117 | |||
118 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | ||
119 | u8 addr, int ds1775, | ||
120 | const char *loc) | ||
121 | { | ||
122 | struct i2c_board_info info; | ||
123 | struct i2c_client *client; | ||
124 | char *name; | ||
125 | |||
126 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
127 | ds1775 ? "ds1775" : "lm75", addr); | ||
123 | 128 | ||
124 | /* Usual rant about sensor names not beeing very consistent in | 129 | /* Usual rant about sensor names not beeing very consistent in |
125 | * the device-tree, oh well ... | 130 | * the device-tree, oh well ... |
126 | * Add more entries below as you deal with more setups | 131 | * Add more entries below as you deal with more setups |
127 | */ | 132 | */ |
128 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) | 133 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) |
129 | lm->sens.name = "hd-temp"; | 134 | name = "hd-temp"; |
130 | else if (!strcmp(loc, "Incoming Air Temp")) | 135 | else if (!strcmp(loc, "Incoming Air Temp")) |
131 | lm->sens.name = "incoming-air-temp"; | 136 | name = "incoming-air-temp"; |
132 | else if (!strcmp(loc, "ODD Temp")) | 137 | else if (!strcmp(loc, "ODD Temp")) |
133 | lm->sens.name = "optical-drive-temp"; | 138 | name = "optical-drive-temp"; |
134 | else if (!strcmp(loc, "HD Temp")) | 139 | else if (!strcmp(loc, "HD Temp")) |
135 | lm->sens.name = "hard-drive-temp"; | 140 | name = "hard-drive-temp"; |
136 | else | 141 | else |
137 | goto fail; | 142 | goto fail; |
138 | 143 | ||
139 | lm->inited = 0; | 144 | memset(&info, 0, sizeof(struct i2c_board_info)); |
140 | lm->sens.ops = &wf_lm75_ops; | 145 | info.addr = (addr >> 1) & 0x7f; |
141 | lm->ds1775 = ds1775; | 146 | info.platform_data = name; |
142 | lm->i2c.addr = (addr >> 1) & 0x7f; | 147 | strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE); |
143 | lm->i2c.adapter = adapter; | ||
144 | lm->i2c.driver = &wf_lm75_driver; | ||
145 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); | ||
146 | |||
147 | rc = i2c_attach_client(&lm->i2c); | ||
148 | if (rc) { | ||
149 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c," | ||
150 | " err %d\n", ds1775 ? "ds1775" : "lm75", | ||
151 | lm->i2c.name, rc); | ||
152 | goto fail; | ||
153 | } | ||
154 | 148 | ||
155 | if (wf_register_sensor(&lm->sens)) { | 149 | client = i2c_new_device(adapter, &info); |
156 | i2c_detach_client(&lm->i2c); | 150 | if (client == NULL) { |
151 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | ||
152 | ds1775 ? "ds1775" : "lm75", name); | ||
157 | goto fail; | 153 | goto fail; |
158 | } | 154 | } |
159 | 155 | ||
160 | return lm; | 156 | /* |
157 | * Let i2c-core delete that device on driver removal. | ||
158 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
159 | */ | ||
160 | list_add_tail(&client->detected, &client->driver->clients); | ||
161 | return client; | ||
161 | fail: | 162 | fail: |
162 | kfree(lm); | ||
163 | return NULL; | 163 | return NULL; |
164 | } | 164 | } |
165 | 165 | ||
@@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | static int wf_lm75_detach(struct i2c_client *client) | 205 | static int wf_lm75_remove(struct i2c_client *client) |
206 | { | 206 | { |
207 | struct wf_lm75_sensor *lm = i2c_to_lm75(client); | 207 | struct wf_lm75_sensor *lm = i2c_get_clientdata(client); |
208 | 208 | ||
209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); | 209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); |
210 | 210 | ||
211 | /* Mark client detached */ | 211 | /* Mark client detached */ |
212 | lm->i2c.adapter = NULL; | 212 | lm->i2c = NULL; |
213 | 213 | ||
214 | /* release sensor */ | 214 | /* release sensor */ |
215 | wf_unregister_sensor(&lm->sens); | 215 | wf_unregister_sensor(&lm->sens); |
216 | 216 | ||
217 | i2c_set_clientdata(client, NULL); | ||
217 | return 0; | 218 | return 0; |
218 | } | 219 | } |
219 | 220 | ||
221 | static const struct i2c_device_id wf_lm75_id[] = { | ||
222 | { "wf_lm75", 0 }, | ||
223 | { "wf_ds1775", 1 }, | ||
224 | { } | ||
225 | }; | ||
226 | |||
227 | static struct i2c_driver wf_lm75_driver = { | ||
228 | .driver = { | ||
229 | .name = "wf_lm75", | ||
230 | }, | ||
231 | .attach_adapter = wf_lm75_attach, | ||
232 | .probe = wf_lm75_probe, | ||
233 | .remove = wf_lm75_remove, | ||
234 | .id_table = wf_lm75_id, | ||
235 | }; | ||
236 | |||
220 | static int __init wf_lm75_sensor_init(void) | 237 | static int __init wf_lm75_sensor_init(void) |
221 | { | 238 | { |
222 | /* Don't register on old machines that use therm_pm72 for now */ | 239 | /* Don't register on old machines that use therm_pm72 for now */ |