aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/ams/ams-i2c.c56
-rw-r--r--drivers/hwmon/ams/ams.h4
-rw-r--r--drivers/i2c/busses/i2c-powermac.c29
3 files changed, 48 insertions, 41 deletions
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
index 957760536a4c..da26de01068e 100644
--- a/drivers/hwmon/ams/ams-i2c.c
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -60,26 +60,34 @@ enum ams_i2c_cmd {
60 AMS_CMD_START, 60 AMS_CMD_START,
61}; 61};
62 62
63static int ams_i2c_attach(struct i2c_adapter *adapter); 63static int ams_i2c_probe(struct i2c_client *client,
64static int ams_i2c_detach(struct i2c_adapter *adapter); 64 const struct i2c_device_id *id);
65static int ams_i2c_remove(struct i2c_client *client);
66
67static const struct i2c_device_id ams_id[] = {
68 { "ams", 0 },
69 { }
70};
71MODULE_DEVICE_TABLE(i2c, ams_id);
65 72
66static struct i2c_driver ams_i2c_driver = { 73static struct i2c_driver ams_i2c_driver = {
67 .driver = { 74 .driver = {
68 .name = "ams", 75 .name = "ams",
69 .owner = THIS_MODULE, 76 .owner = THIS_MODULE,
70 }, 77 },
71 .attach_adapter = ams_i2c_attach, 78 .probe = ams_i2c_probe,
72 .detach_adapter = ams_i2c_detach, 79 .remove = ams_i2c_remove,
80 .id_table = ams_id,
73}; 81};
74 82
75static s32 ams_i2c_read(u8 reg) 83static s32 ams_i2c_read(u8 reg)
76{ 84{
77 return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg); 85 return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
78} 86}
79 87
80static int ams_i2c_write(u8 reg, u8 value) 88static int ams_i2c_write(u8 reg, u8 value)
81{ 89{
82 return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value); 90 return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
83} 91}
84 92
85static int ams_i2c_cmd(enum ams_i2c_cmd cmd) 93static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
@@ -152,9 +160,9 @@ static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
152 *z = ams_i2c_read(AMS_DATAZ); 160 *z = ams_i2c_read(AMS_DATAZ);
153} 161}
154 162
155static int ams_i2c_attach(struct i2c_adapter *adapter) 163static int ams_i2c_probe(struct i2c_client *client,
164 const struct i2c_device_id *id)
156{ 165{
157 unsigned long bus;
158 int vmaj, vmin; 166 int vmaj, vmin;
159 int result; 167 int result;
160 168
@@ -162,17 +170,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter)
162 if (unlikely(ams_info.has_device)) 170 if (unlikely(ams_info.has_device))
163 return -ENODEV; 171 return -ENODEV;
164 172
165 if (strncmp(adapter->name, "uni-n", 5)) 173 ams_info.i2c_client = client;
166 return -ENODEV;
167
168 bus = simple_strtoul(adapter->name + 6, NULL, 10);
169 if (bus != ams_info.i2c_bus)
170 return -ENODEV;
171
172 ams_info.i2c_client.addr = ams_info.i2c_address;
173 ams_info.i2c_client.adapter = adapter;
174 ams_info.i2c_client.driver = &ams_i2c_driver;
175 strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");
176 174
177 if (ams_i2c_cmd(AMS_CMD_RESET)) { 175 if (ams_i2c_cmd(AMS_CMD_RESET)) {
178 printk(KERN_INFO "ams: Failed to reset the device\n"); 176 printk(KERN_INFO "ams: Failed to reset the device\n");
@@ -237,7 +235,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter)
237 return 0; 235 return 0;
238} 236}
239 237
240static int ams_i2c_detach(struct i2c_adapter *adapter) 238static int ams_i2c_remove(struct i2c_client *client)
241{ 239{
242 if (ams_info.has_device) { 240 if (ams_info.has_device) {
243 /* Disable interrupts */ 241 /* Disable interrupts */
@@ -261,9 +259,7 @@ static void ams_i2c_exit(void)
261 259
262int __init ams_i2c_init(struct device_node *np) 260int __init ams_i2c_init(struct device_node *np)
263{ 261{
264 char *tmp_bus;
265 int result; 262 int result;
266 const u32 *prop;
267 263
268 mutex_lock(&ams_info.lock); 264 mutex_lock(&ams_info.lock);
269 265
@@ -275,24 +271,8 @@ int __init ams_i2c_init(struct device_node *np)
275 ams_info.clear_irq = ams_i2c_clear_irq; 271 ams_info.clear_irq = ams_i2c_clear_irq;
276 ams_info.bustype = BUS_I2C; 272 ams_info.bustype = BUS_I2C;
277 273
278 /* look for bus either using "reg" or by path */
279 prop = of_get_property(ams_info.of_node, "reg", NULL);
280 if (!prop) {
281 result = -ENODEV;
282
283 goto exit;
284 }
285
286 tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
287 if (tmp_bus)
288 ams_info.i2c_bus = *(tmp_bus + 9) - '0';
289 else
290 ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
291 ams_info.i2c_address = ((*prop) & 0xff) >> 1;
292
293 result = i2c_add_driver(&ams_i2c_driver); 274 result = i2c_add_driver(&ams_i2c_driver);
294 275
295exit:
296 mutex_unlock(&ams_info.lock); 276 mutex_unlock(&ams_info.lock);
297 277
298 return result; 278 return result;
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
index 221ef6915a5f..5ed387b0bd9a 100644
--- a/drivers/hwmon/ams/ams.h
+++ b/drivers/hwmon/ams/ams.h
@@ -46,9 +46,7 @@ struct ams {
46 46
47#ifdef CONFIG_SENSORS_AMS_I2C 47#ifdef CONFIG_SENSORS_AMS_I2C
48 /* I2C properties */ 48 /* I2C properties */
49 int i2c_bus; 49 struct i2c_client *i2c_client;
50 int i2c_address;
51 struct i2c_client i2c_client;
52#endif 50#endif
53 51
54 /* Joystick emulation */ 52 /* Joystick emulation */
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 0e7b1c6724aa..60ca91745e55 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -259,6 +259,35 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev)
259 } 259 }
260 260
261 printk(KERN_INFO "PowerMac i2c bus %s registered\n", name); 261 printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
262
263 if (!strncmp(basename, "uni-n", 5)) {
264 struct device_node *np;
265 const u32 *prop;
266 struct i2c_board_info info;
267
268 /* Instantiate I2C motion sensor if present */
269 np = of_find_node_by_name(NULL, "accelerometer");
270 if (np && of_device_is_compatible(np, "AAPL,accelerometer_1") &&
271 (prop = of_get_property(np, "reg", NULL))) {
272 int i2c_bus;
273 const char *tmp_bus;
274
275 /* look for bus either using "reg" or by path */
276 tmp_bus = strstr(np->full_name, "/i2c-bus@");
277 if (tmp_bus)
278 i2c_bus = *(tmp_bus + 9) - '0';
279 else
280 i2c_bus = ((*prop) >> 8) & 0x0f;
281
282 if (pmac_i2c_get_channel(bus) == i2c_bus) {
283 memset(&info, 0, sizeof(struct i2c_board_info));
284 info.addr = ((*prop) & 0xff) >> 1;
285 strlcpy(info.type, "ams", I2C_NAME_SIZE);
286 i2c_new_device(adapter, &info);
287 }
288 }
289 }
290
262 return rc; 291 return rc;
263} 292}
264 293