]>
Commit | Line | Data |
---|---|---|
83f7649c GR |
1 | /* |
2 | * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller | |
3 | * and Digital Power Monitor | |
4 | * | |
5 | * Copyright (c) 2011 Ericsson AB. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | */ | |
17 | ||
18 | #include <linux/kernel.h> | |
19 | #include <linux/module.h> | |
20 | #include <linux/init.h> | |
21 | #include <linux/err.h> | |
22 | #include <linux/slab.h> | |
23 | #include <linux/i2c.h> | |
24 | #include "pmbus.h" | |
25 | ||
26 | #define ADM1275_PMON_CONFIG 0xd4 | |
27 | ||
28 | #define ADM1275_VIN_VOUT_SELECT (1 << 6) | |
29 | #define ADM1275_VRANGE (1 << 5) | |
30 | ||
31 | static int adm1275_probe(struct i2c_client *client, | |
32 | const struct i2c_device_id *id) | |
33 | { | |
34 | int config; | |
3b33ca41 | 35 | int ret; |
83f7649c GR |
36 | struct pmbus_driver_info *info; |
37 | ||
38 | if (!i2c_check_functionality(client->adapter, | |
39 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) | |
40 | return -ENODEV; | |
41 | ||
42 | info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); | |
43 | if (!info) | |
44 | return -ENOMEM; | |
45 | ||
46 | config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); | |
3b33ca41 GR |
47 | if (config < 0) { |
48 | ret = config; | |
49 | goto err_mem; | |
50 | } | |
83f7649c GR |
51 | |
52 | info->pages = 1; | |
53 | info->direct[PSC_VOLTAGE_IN] = true; | |
54 | info->direct[PSC_VOLTAGE_OUT] = true; | |
55 | info->direct[PSC_CURRENT_OUT] = true; | |
7e97bbba | 56 | info->m[PSC_CURRENT_OUT] = 807; |
83f7649c GR |
57 | info->b[PSC_CURRENT_OUT] = 20475; |
58 | info->R[PSC_CURRENT_OUT] = -1; | |
59 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | |
60 | ||
61 | if (config & ADM1275_VRANGE) { | |
7e97bbba | 62 | info->m[PSC_VOLTAGE_IN] = 19199; |
83f7649c GR |
63 | info->b[PSC_VOLTAGE_IN] = 0; |
64 | info->R[PSC_VOLTAGE_IN] = -2; | |
7e97bbba | 65 | info->m[PSC_VOLTAGE_OUT] = 19199; |
83f7649c GR |
66 | info->b[PSC_VOLTAGE_OUT] = 0; |
67 | info->R[PSC_VOLTAGE_OUT] = -2; | |
68 | } else { | |
7e97bbba | 69 | info->m[PSC_VOLTAGE_IN] = 6720; |
83f7649c GR |
70 | info->b[PSC_VOLTAGE_IN] = 0; |
71 | info->R[PSC_VOLTAGE_IN] = -1; | |
7e97bbba | 72 | info->m[PSC_VOLTAGE_OUT] = 6720; |
83f7649c GR |
73 | info->b[PSC_VOLTAGE_OUT] = 0; |
74 | info->R[PSC_VOLTAGE_OUT] = -1; | |
75 | } | |
76 | ||
77 | if (config & ADM1275_VIN_VOUT_SELECT) | |
78 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | |
79 | else | |
80 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | |
81 | ||
3b33ca41 GR |
82 | ret = pmbus_do_probe(client, id, info); |
83 | if (ret) | |
84 | goto err_mem; | |
85 | return 0; | |
86 | ||
87 | err_mem: | |
88 | kfree(info); | |
89 | return ret; | |
83f7649c GR |
90 | } |
91 | ||
92 | static int adm1275_remove(struct i2c_client *client) | |
93 | { | |
94 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
95 | int ret; | |
96 | ||
97 | ret = pmbus_do_remove(client); | |
98 | kfree(info); | |
99 | return ret; | |
100 | } | |
101 | ||
102 | static const struct i2c_device_id adm1275_id[] = { | |
103 | {"adm1275", 0}, | |
104 | { } | |
105 | }; | |
106 | MODULE_DEVICE_TABLE(i2c, adm1275_id); | |
107 | ||
108 | static struct i2c_driver adm1275_driver = { | |
109 | .driver = { | |
110 | .name = "adm1275", | |
111 | }, | |
112 | .probe = adm1275_probe, | |
113 | .remove = adm1275_remove, | |
114 | .id_table = adm1275_id, | |
115 | }; | |
116 | ||
117 | static int __init adm1275_init(void) | |
118 | { | |
119 | return i2c_add_driver(&adm1275_driver); | |
120 | } | |
121 | ||
122 | static void __exit adm1275_exit(void) | |
123 | { | |
124 | i2c_del_driver(&adm1275_driver); | |
125 | } | |
126 | ||
127 | MODULE_AUTHOR("Guenter Roeck"); | |
128 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275"); | |
129 | MODULE_LICENSE("GPL"); | |
130 | module_init(adm1275_init); | |
131 | module_exit(adm1275_exit); |