Skip to content

Commit

Permalink
Align with upstream driver
Browse files Browse the repository at this point in the history
No alert support in this branch.

Signed-off-by: Guenter Roeck <[email protected]>
  • Loading branch information
groeck committed Jan 16, 2013
1 parent 33638e2 commit 37324ac
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 501 deletions.
119 changes: 7 additions & 112 deletions adm1275.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,6 @@ enum chips { adm1075, adm1275, adm1276 };
#define ADM1075_IRANGE_25 (1 << 3)
#define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4))

#define ADM1275_ALERT1_CONFIG 0xd5
#define ADM1275_ALERT2_CONFIG 0xd6

#define ADM1275_CONVERT_EN (1 << 2)
#define ADM1275_GPO_EN (1 << 1)
#define ADM1275_GPO_DATA (1 << 0)
#define ADM1275_SMBALERT_MASK (ADM1275_CONVERT_EN | ADM1275_GPO_EN \
| ADM1275_GPO_DATA)
#define ADM1275_ALERT_MASK 0xf81f /* hw-generated alarms and
configuration bits */

#define ADM1275_IOUT_WARN2_LIMIT 0xd7
#define ADM1275_DEVICE_CONFIG 0xd8

Expand All @@ -67,8 +56,6 @@ enum chips { adm1075, adm1275, adm1276 };
struct adm1275_data {
int id;
bool have_oc_fault;
u16 alert1, alert2;
u16 alert1_curr, alert2_curr;
struct pmbus_driver_info info;
};

Expand Down Expand Up @@ -230,65 +217,6 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
return ret;
}

/*
* ADM1275 and ADM1276 keep generating SMBUS alerts for software-implemented
* alarms, even if there is no change in alarm status. This causes a lot of I2C
* bus traffic as well as "Duplicate alert" kernel log warnings.
* Since this is undesirable, disable generation of SMBus alerts for the
* affected alarm bits while any of the alarms is active. Re-enable SMBus alarm
* notifications if no further alarms are pending.
* This means that after the first warning alarm bit is set, subsequent alarm
* bits are only detected by the PMBus core polling function, which may result
* in slight reporting delays (up to 1 second) if another alarm is activated.
* This may not be optimal, but is still better than the overhead of having to
* handle continuous SMBus interrupts.
*/
static void adm1275_alert_handler(struct i2c_client *client, bool alarm)
{
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
struct adm1275_data *data = to_adm1275_data(info);
int reg;

if (data->id == adm1275 && (data->alert1 & ADM1275_SMBALERT_MASK) == 0) {
reg = data->alert1_curr;
if (alarm) {
reg &= ADM1275_ALERT_MASK;
if (reg != data->alert1_curr) {
i2c_smbus_write_word_data(client,
ADM1275_ALERT1_CONFIG,
reg);
data->alert1_curr = reg;
}
} else {
if (reg != data->alert1) {
i2c_smbus_write_word_data(client,
ADM1275_ALERT1_CONFIG,
data->alert1);
data->alert1_curr = data->alert1;
}
}
}
if ((data->alert2 & ADM1275_SMBALERT_MASK) == 0) {
reg = data->alert2_curr;
if (alarm) {
reg &= ADM1275_ALERT_MASK;
if (reg != data->alert2_curr) {
i2c_smbus_write_word_data(client,
ADM1275_ALERT2_CONFIG,
reg);
data->alert2_curr = reg;
}
} else {
if (reg != data->alert2) {
i2c_smbus_write_word_data(client,
ADM1275_ALERT2_CONFIG,
data->alert2);
data->alert2_curr = data->alert2;
}
}
}
}

static const struct i2c_device_id adm1275_id[] = {
{ "adm1075", adm1075 },
{ "adm1275", adm1275 },
Expand All @@ -309,15 +237,9 @@ static int adm1275_probe(struct i2c_client *client,

if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA
| I2C_FUNC_SMBUS_READ_WORD_DATA
| I2C_FUNC_SMBUS_BLOCK_DATA))
return -ENODEV;

data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;

ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, block_buffer);
if (ret < 0) {
dev_err(&client->dev, "Failed to read Manufacturer ID\n");
Expand Down Expand Up @@ -355,19 +277,12 @@ static int adm1275_probe(struct i2c_client *client,
if (device_config < 0)
return device_config;

data->id = mid->driver_data;
if (data->id == adm1275) {
data->alert1 = i2c_smbus_read_word_data(client,
ADM1275_ALERT1_CONFIG);
if (data->alert1 < 0)
return data->alert1;
data->alert1_curr = data->alert1;
}
data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;

data->alert2 = i2c_smbus_read_word_data(client, ADM1275_ALERT2_CONFIG);
if (data->alert2 < 0)
return data->alert2;
data->alert2_curr = data->alert2;
data->id = mid->driver_data;

info = &data->info;

Expand All @@ -383,7 +298,6 @@ static int adm1275_probe(struct i2c_client *client,
info->read_word_data = adm1275_read_word_data;
info->read_byte_data = adm1275_read_byte_data;
info->write_word_data = adm1275_write_word_data;
info->alert_handler = adm1275_alert_handler;

if (data->id == adm1075) {
info->m[PSC_VOLTAGE_IN] = 27169;
Expand Down Expand Up @@ -467,36 +381,17 @@ static int adm1275_probe(struct i2c_client *client,
return pmbus_do_probe(client, id, info);
}

static int adm1275_remove(struct i2c_client *client)
{
pmbus_do_remove(client);
return 0;
}

static struct i2c_driver adm1275_driver = {
.driver = {
.name = "adm1275",
},
.probe = adm1275_probe,
.remove = adm1275_remove,
#if defined(CONFIG_I2C_SMBUS) || defined(CONFIG_I2C_PMBUS_MODULE)
.alert = pmbus_do_alert,
#endif
.remove = pmbus_do_remove,
.id_table = adm1275_id,
};

static int __init adm1275_init(void)
{
return i2c_add_driver(&adm1275_driver);
}

static void __exit adm1275_exit(void)
{
i2c_del_driver(&adm1275_driver);
}
module_i2c_driver(adm1275_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles");
MODULE_LICENSE("GPL");
module_init(adm1275_init);
module_exit(adm1275_exit);
12 changes: 1 addition & 11 deletions lm25066.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,18 +314,8 @@ static struct i2c_driver lm25066_driver = {
.id_table = lm25066_id,
};

static int __init lm25066_init(void)
{
return i2c_add_driver(&lm25066_driver);
}

static void __exit lm25066_exit(void)
{
i2c_del_driver(&lm25066_driver);
}
module_i2c_driver(lm25066_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066");
MODULE_LICENSE("GPL");
module_init(lm25066_init);
module_exit(lm25066_exit);
15 changes: 1 addition & 14 deletions ltc2978.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,24 +368,11 @@ static struct i2c_driver ltc2978_driver = {
},
.probe = ltc2978_probe,
.remove = pmbus_do_remove,
#if defined(CONFIG_I2C_SMBUS) || defined(CONFIG_I2C_PMBUS_MODULE)
.alert = pmbus_do_alert,
#endif
.id_table = ltc2978_id,
};

static int __init ltc2978_init(void)
{
return i2c_add_driver(&ltc2978_driver);
}

static void __exit ltc2978_exit(void)
{
i2c_del_driver(&ltc2978_driver);
}
module_i2c_driver(ltc2978_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880");
MODULE_LICENSE("GPL");
module_init(ltc2978_init);
module_exit(ltc2978_exit);
12 changes: 1 addition & 11 deletions max16064.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,8 @@ static struct i2c_driver max16064_driver = {
.id_table = max16064_id,
};

static int __init max16064_init(void)
{
return i2c_add_driver(&max16064_driver);
}

static void __exit max16064_exit(void)
{
i2c_del_driver(&max16064_driver);
}
module_i2c_driver(max16064_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064");
MODULE_LICENSE("GPL");
module_init(max16064_init);
module_exit(max16064_exit);
55 changes: 42 additions & 13 deletions max34440.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Hardware monitoring driver for Maxim MAX34440/MAX34441
*
* Copyright (c) 2011 Ericsson AB.
* Copyright (c) 2012 Guenter Roeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -25,7 +26,7 @@
#include <linux/i2c.h>
#include "pmbus.h"

enum chips { max34440, max34441, max34446, max34460 };
enum chips { max34440, max34441, max34446, max34460, max34461 };

#define MAX34440_MFR_VOUT_PEAK 0xd4
#define MAX34440_MFR_IOUT_PEAK 0xd5
Expand Down Expand Up @@ -87,7 +88,8 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
MAX34446_MFR_POUT_PEAK);
break;
case PMBUS_VIRT_READ_TEMP_AVG:
if (data->id != max34446 && data->id != max34460)
if (data->id != max34446 && data->id != max34460 &&
data->id != max34461)
return -ENXIO;
ret = pmbus_read_word_data(client, page,
MAX34446_MFR_TEMPERATURE_AVG);
Expand Down Expand Up @@ -353,6 +355,42 @@ static struct pmbus_driver_info max34440_info[] = {
.read_word_data = max34440_read_word_data,
.write_word_data = max34440_write_word_data,
},
[max34461] = {
.pages = 23,
.format[PSC_VOLTAGE_OUT] = direct,
.format[PSC_TEMPERATURE] = direct,
.m[PSC_VOLTAGE_OUT] = 1,
.b[PSC_VOLTAGE_OUT] = 0,
.R[PSC_VOLTAGE_OUT] = 3,
.m[PSC_TEMPERATURE] = 1,
.b[PSC_TEMPERATURE] = 0,
.R[PSC_TEMPERATURE] = 2,
.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
/* page 16 is reserved */
.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.read_byte_data = max34440_read_byte_data,
.read_word_data = max34440_read_word_data,
.write_word_data = max34440_write_word_data,
},
};

static int max34440_probe(struct i2c_client *client,
Expand All @@ -375,6 +413,7 @@ static const struct i2c_device_id max34440_id[] = {
{"max34441", max34441},
{"max34446", max34446},
{"max34460", max34460},
{"max34461", max34461},
{}
};
MODULE_DEVICE_TABLE(i2c, max34440_id);
Expand All @@ -389,18 +428,8 @@ static struct i2c_driver max34440_driver = {
.id_table = max34440_id,
};

static int __init max34440_init(void)
{
return i2c_add_driver(&max34440_driver);
}

static void __exit max34440_exit(void)
{
i2c_del_driver(&max34440_driver);
}
module_i2c_driver(max34440_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
MODULE_LICENSE("GPL");
module_init(max34440_init);
module_exit(max34440_exit);
12 changes: 1 addition & 11 deletions max8688.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,8 @@ static struct i2c_driver max8688_driver = {
.id_table = max8688_id,
};

static int __init max8688_init(void)
{
return i2c_add_driver(&max8688_driver);
}

static void __exit max8688_exit(void)
{
i2c_del_driver(&max8688_driver);
}
module_i2c_driver(max8688_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688");
MODULE_LICENSE("GPL");
module_init(max8688_init);
module_exit(max8688_exit);
12 changes: 1 addition & 11 deletions pmbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,8 @@ static struct i2c_driver pmbus_driver = {
.id_table = pmbus_id,
};

static int __init pmbus_init(void)
{
return i2c_add_driver(&pmbus_driver);
}

static void __exit pmbus_exit(void)
{
i2c_del_driver(&pmbus_driver);
}
module_i2c_driver(pmbus_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("Generic PMBus driver");
MODULE_LICENSE("GPL");
module_init(pmbus_init);
module_exit(pmbus_exit);
Loading

0 comments on commit 37324ac

Please sign in to comment.