Skip to content

Commit

Permalink
windfarm: Convert to new-style i2c drivers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean Delvare committed Jun 15, 2009
1 parent 1b9f37d commit 351ca3e
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 144 deletions.
129 changes: 73 additions & 56 deletions drivers/macintosh/windfarm_lm75_sensor.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,22 @@
struct wf_lm75_sensor {
int ds1775 : 1;
int inited : 1;
struct i2c_client i2c;
struct i2c_client *i2c;
struct wf_sensor sens;
};
#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
#define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c)

static int wf_lm75_attach(struct i2c_adapter *adapter);
static int wf_lm75_detach(struct i2c_client *client);

static struct i2c_driver wf_lm75_driver = {
.driver = {
.name = "wf_lm75",
},
.attach_adapter = wf_lm75_attach,
.detach_client = wf_lm75_detach,
};

static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
{
struct wf_lm75_sensor *lm = wf_to_lm75(sr);
s32 data;

if (lm->i2c.adapter == NULL)
if (lm->i2c == NULL)
return -ENODEV;

/* Init chip if necessary */
if (!lm->inited) {
u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1);
u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1);

DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
sr->name, cfg);
Expand All @@ -73,15 +61,15 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
* the firmware for now
*/
cfg_new = cfg & ~0x01;
i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new);
i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new);
lm->inited = 1;

/* If we just powered it up, let's wait 200 ms */
msleep(200);
}

/* Read temperature register */
data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0));
data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0));
data <<= 8;
*value = data;

Expand All @@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr)
{
struct wf_lm75_sensor *lm = wf_to_lm75(sr);

/* check if client is registered and detach from i2c */
if (lm->i2c.adapter) {
i2c_detach_client(&lm->i2c);
lm->i2c.adapter = NULL;
}

kfree(lm);
}

Expand All @@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = {
.owner = THIS_MODULE,
};

static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
u8 addr, int ds1775,
const char *loc)
static int wf_lm75_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct wf_lm75_sensor *lm;
int rc;

DBG("wf_lm75: creating %s device at address 0x%02x\n",
ds1775 ? "ds1775" : "lm75", addr);

lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
if (lm == NULL)
return NULL;
return -ENODEV;

lm->inited = 0;
lm->ds1775 = id->driver_data;
lm->i2c = client;
lm->sens.name = client->dev.platform_data;
lm->sens.ops = &wf_lm75_ops;
i2c_set_clientdata(client, lm);

rc = wf_register_sensor(&lm->sens);
if (rc) {
i2c_set_clientdata(client, NULL);
kfree(lm);
}

return rc;
}

static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
u8 addr, int ds1775,
const char *loc)
{
struct i2c_board_info info;
struct i2c_client *client;
char *name;

DBG("wf_lm75: creating %s device at address 0x%02x\n",
ds1775 ? "ds1775" : "lm75", addr);

/* Usual rant about sensor names not beeing very consistent in
* the device-tree, oh well ...
* Add more entries below as you deal with more setups
*/
if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
lm->sens.name = "hd-temp";
name = "hd-temp";
else if (!strcmp(loc, "Incoming Air Temp"))
lm->sens.name = "incoming-air-temp";
name = "incoming-air-temp";
else if (!strcmp(loc, "ODD Temp"))
lm->sens.name = "optical-drive-temp";
name = "optical-drive-temp";
else if (!strcmp(loc, "HD Temp"))
lm->sens.name = "hard-drive-temp";
name = "hard-drive-temp";
else
goto fail;

lm->inited = 0;
lm->sens.ops = &wf_lm75_ops;
lm->ds1775 = ds1775;
lm->i2c.addr = (addr >> 1) & 0x7f;
lm->i2c.adapter = adapter;
lm->i2c.driver = &wf_lm75_driver;
strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);

rc = i2c_attach_client(&lm->i2c);
if (rc) {
printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
" err %d\n", ds1775 ? "ds1775" : "lm75",
lm->i2c.name, rc);
goto fail;
}
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = (addr >> 1) & 0x7f;
info.platform_data = name;
strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE);

if (wf_register_sensor(&lm->sens)) {
i2c_detach_client(&lm->i2c);
client = i2c_new_device(adapter, &info);
if (client == NULL) {
printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
ds1775 ? "ds1775" : "lm75", name);
goto fail;
}

return lm;
/*
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
list_add_tail(&client->detected, &client->driver->clients);
return client;
fail:
kfree(lm);
return NULL;
}

Expand Down Expand Up @@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
return 0;
}

static int wf_lm75_detach(struct i2c_client *client)
static int wf_lm75_remove(struct i2c_client *client)
{
struct wf_lm75_sensor *lm = i2c_to_lm75(client);
struct wf_lm75_sensor *lm = i2c_get_clientdata(client);

DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);

/* Mark client detached */
lm->i2c.adapter = NULL;
lm->i2c = NULL;

/* release sensor */
wf_unregister_sensor(&lm->sens);

i2c_set_clientdata(client, NULL);
return 0;
}

static const struct i2c_device_id wf_lm75_id[] = {
{ "wf_lm75", 0 },
{ "wf_ds1775", 1 },
{ }
};

static struct i2c_driver wf_lm75_driver = {
.driver = {
.name = "wf_lm75",
},
.attach_adapter = wf_lm75_attach,
.probe = wf_lm75_probe,
.remove = wf_lm75_remove,
.id_table = wf_lm75_id,
};

static int __init wf_lm75_sensor_init(void)
{
/* Don't register on old machines that use therm_pm72 for now */
Expand Down
103 changes: 61 additions & 42 deletions drivers/macintosh/windfarm_max6690_sensor.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,22 @@
#define MAX6690_EXTERNAL_TEMP 1

struct wf_6690_sensor {
struct i2c_client i2c;
struct i2c_client *i2c;
struct wf_sensor sens;
};

#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens)
#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c)

static int wf_max6690_attach(struct i2c_adapter *adapter);
static int wf_max6690_detach(struct i2c_client *client);

static struct i2c_driver wf_max6690_driver = {
.driver = {
.name = "wf_max6690",
},
.attach_adapter = wf_max6690_attach,
.detach_client = wf_max6690_detach,
};

static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
{
struct wf_6690_sensor *max = wf_to_6690(sr);
s32 data;

if (max->i2c.adapter == NULL)
if (max->i2c == NULL)
return -ENODEV;

/* chip gets initialized by firmware */
data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);
if (data < 0)
return data;
*value = data << 16;
Expand All @@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr)
{
struct wf_6690_sensor *max = wf_to_6690(sr);

if (max->i2c.adapter) {
i2c_detach_client(&max->i2c);
max->i2c.adapter = NULL;
}
kfree(max);
}

Expand All @@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = {
.owner = THIS_MODULE,
};

static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
const char *loc)
static int wf_max6690_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct wf_6690_sensor *max;
char *name;
int rc;

max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
if (max == NULL) {
printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
"no memory\n", loc);
return;
printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
"no memory\n");
return -ENOMEM;
}

max->i2c = client;
max->sens.name = client->dev.platform_data;
max->sens.ops = &wf_max6690_ops;
i2c_set_clientdata(client, max);

rc = wf_register_sensor(&max->sens);
if (rc) {
i2c_set_clientdata(client, NULL);
kfree(max);
}

return rc;
}

static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
u8 addr, const char *loc)
{
struct i2c_board_info info;
struct i2c_client *client;
char *name;

if (!strcmp(loc, "BACKSIDE"))
name = "backside-temp";
else if (!strcmp(loc, "NB Ambient"))
Expand All @@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
else
goto fail;

max->sens.ops = &wf_max6690_ops;
max->sens.name = name;
max->i2c.addr = addr >> 1;
max->i2c.adapter = adapter;
max->i2c.driver = &wf_max6690_driver;
strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = addr >> 1;
info.platform_data = name;
strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE);

if (i2c_attach_client(&max->i2c)) {
client = i2c_new_device(adapter, &info);
if (client == NULL) {
printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
goto fail;
}

if (wf_register_sensor(&max->sens)) {
i2c_detach_client(&max->i2c);
goto fail;
}

return;
/*
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
list_add_tail(&client->detected, &client->driver->clients);
return client;

fail:
kfree(max);
return NULL;
}

static int wf_max6690_attach(struct i2c_adapter *adapter)
Expand Down Expand Up @@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
return 0;
}

static int wf_max6690_detach(struct i2c_client *client)
static int wf_max6690_remove(struct i2c_client *client)
{
struct wf_6690_sensor *max = i2c_to_6690(client);
struct wf_6690_sensor *max = i2c_get_clientdata(client);

max->i2c.adapter = NULL;
max->i2c = NULL;
wf_unregister_sensor(&max->sens);

return 0;
}

static const struct i2c_device_id wf_max6690_id[] = {
{ "wf_max6690", 0 },
{ }
};

static struct i2c_driver wf_max6690_driver = {
.driver = {
.name = "wf_max6690",
},
.attach_adapter = wf_max6690_attach,
.probe = wf_max6690_probe,
.remove = wf_max6690_remove,
.id_table = wf_max6690_id,
};

static int __init wf_max6690_sensor_init(void)
{
/* Don't register on old machines that use therm_pm72 for now */
Expand Down
Loading

0 comments on commit 351ca3e

Please sign in to comment.