AMS_CMD_START,
};
-static int ams_i2c_attach(struct i2c_adapter *adapter);
-static int ams_i2c_detach(struct i2c_adapter *adapter);
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int ams_i2c_remove(struct i2c_client *client);
+
+static const struct i2c_device_id ams_id[] = {
+ { "ams", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ams_id);
static struct i2c_driver ams_i2c_driver = {
.driver = {
.name = "ams",
.owner = THIS_MODULE,
},
- .attach_adapter = ams_i2c_attach,
- .detach_adapter = ams_i2c_detach,
+ .probe = ams_i2c_probe,
+ .remove = ams_i2c_remove,
+ .id_table = ams_id,
};
static s32 ams_i2c_read(u8 reg)
{
- return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg);
+ return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
}
static int ams_i2c_write(u8 reg, u8 value)
{
- return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value);
+ return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
}
static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
*z = ams_i2c_read(AMS_DATAZ);
}
-static int ams_i2c_attach(struct i2c_adapter *adapter)
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- unsigned long bus;
int vmaj, vmin;
int result;
if (unlikely(ams_info.has_device))
return -ENODEV;
- if (strncmp(adapter->name, "uni-n", 5))
- return -ENODEV;
-
- bus = simple_strtoul(adapter->name + 6, NULL, 10);
- if (bus != ams_info.i2c_bus)
- return -ENODEV;
-
- ams_info.i2c_client.addr = ams_info.i2c_address;
- ams_info.i2c_client.adapter = adapter;
- ams_info.i2c_client.driver = &ams_i2c_driver;
- strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");
+ ams_info.i2c_client = client;
if (ams_i2c_cmd(AMS_CMD_RESET)) {
printk(KERN_INFO "ams: Failed to reset the device\n");
return 0;
}
-static int ams_i2c_detach(struct i2c_adapter *adapter)
+static int ams_i2c_remove(struct i2c_client *client)
{
if (ams_info.has_device) {
/* Disable interrupts */
int __init ams_i2c_init(struct device_node *np)
{
- char *tmp_bus;
int result;
- const u32 *prop;
mutex_lock(&ams_info.lock);
ams_info.clear_irq = ams_i2c_clear_irq;
ams_info.bustype = BUS_I2C;
- /* look for bus either using "reg" or by path */
- prop = of_get_property(ams_info.of_node, "reg", NULL);
- if (!prop) {
- result = -ENODEV;
-
- goto exit;
- }
-
- tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
- if (tmp_bus)
- ams_info.i2c_bus = *(tmp_bus + 9) - '0';
- else
- ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
- ams_info.i2c_address = ((*prop) & 0xff) >> 1;
-
result = i2c_add_driver(&ams_i2c_driver);
-exit:
mutex_unlock(&ams_info.lock);
return result;
}
printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
+
+ if (!strncmp(basename, "uni-n", 5)) {
+ struct device_node *np;
+ const u32 *prop;
+ struct i2c_board_info info;
+
+ /* Instantiate I2C motion sensor if present */
+ np = of_find_node_by_name(NULL, "accelerometer");
+ if (np && of_device_is_compatible(np, "AAPL,accelerometer_1") &&
+ (prop = of_get_property(np, "reg", NULL))) {
+ int i2c_bus;
+ const char *tmp_bus;
+
+ /* look for bus either using "reg" or by path */
+ tmp_bus = strstr(np->full_name, "/i2c-bus@");
+ if (tmp_bus)
+ i2c_bus = *(tmp_bus + 9) - '0';
+ else
+ i2c_bus = ((*prop) >> 8) & 0x0f;
+
+ if (pmac_i2c_get_channel(bus) == i2c_bus) {
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = ((*prop) & 0xff) >> 1;
+ strlcpy(info.type, "ams", I2C_NAME_SIZE);
+ i2c_new_device(adapter, &info);
+ }
+ }
+ }
+
return rc;
}