ipv6: check for IPv4 mapped addresses when connecting IPv6 sockets
[pandora-kernel.git] / drivers / hwmon / pmbus / adm1275.c
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_PEAK_IOUT               0xd0
27 #define ADM1275_PEAK_VIN                0xd1
28 #define ADM1275_PEAK_VOUT               0xd2
29 #define ADM1275_PMON_CONFIG             0xd4
30
31 #define ADM1275_VIN_VOUT_SELECT         (1 << 6)
32 #define ADM1275_VRANGE                  (1 << 5)
33
34 static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
35 {
36         int ret;
37
38         if (page)
39                 return -EINVAL;
40
41         switch (reg) {
42         case PMBUS_VIRT_READ_IOUT_MAX:
43                 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
44                 break;
45         case PMBUS_VIRT_READ_VOUT_MAX:
46                 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VOUT);
47                 break;
48         case PMBUS_VIRT_READ_VIN_MAX:
49                 ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
50                 break;
51         case PMBUS_VIRT_RESET_IOUT_HISTORY:
52         case PMBUS_VIRT_RESET_VOUT_HISTORY:
53         case PMBUS_VIRT_RESET_VIN_HISTORY:
54                 ret = 0;
55                 break;
56         default:
57                 ret = -ENODATA;
58                 break;
59         }
60         return ret;
61 }
62
63 static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
64                                    u16 word)
65 {
66         int ret;
67
68         if (page)
69                 return -EINVAL;
70
71         switch (reg) {
72         case PMBUS_VIRT_RESET_IOUT_HISTORY:
73                 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0);
74                 break;
75         case PMBUS_VIRT_RESET_VOUT_HISTORY:
76                 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0);
77                 break;
78         case PMBUS_VIRT_RESET_VIN_HISTORY:
79                 ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0);
80                 break;
81         default:
82                 ret = -ENODATA;
83                 break;
84         }
85         return ret;
86 }
87
88 static int adm1275_probe(struct i2c_client *client,
89                          const struct i2c_device_id *id)
90 {
91         int config;
92         int ret;
93         struct pmbus_driver_info *info;
94
95         if (!i2c_check_functionality(client->adapter,
96                                      I2C_FUNC_SMBUS_READ_BYTE_DATA))
97                 return -ENODEV;
98
99         info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL);
100         if (!info)
101                 return -ENOMEM;
102
103         config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
104         if (config < 0) {
105                 ret = config;
106                 goto err_mem;
107         }
108
109         info->pages = 1;
110         info->format[PSC_VOLTAGE_IN] = direct;
111         info->format[PSC_VOLTAGE_OUT] = direct;
112         info->format[PSC_CURRENT_OUT] = direct;
113         info->m[PSC_CURRENT_OUT] = 807;
114         info->b[PSC_CURRENT_OUT] = 20475;
115         info->R[PSC_CURRENT_OUT] = -1;
116         info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
117
118         info->read_word_data = adm1275_read_word_data;
119         info->write_word_data = adm1275_write_word_data;
120
121         if (config & ADM1275_VRANGE) {
122                 info->m[PSC_VOLTAGE_IN] = 19199;
123                 info->b[PSC_VOLTAGE_IN] = 0;
124                 info->R[PSC_VOLTAGE_IN] = -2;
125                 info->m[PSC_VOLTAGE_OUT] = 19199;
126                 info->b[PSC_VOLTAGE_OUT] = 0;
127                 info->R[PSC_VOLTAGE_OUT] = -2;
128         } else {
129                 info->m[PSC_VOLTAGE_IN] = 6720;
130                 info->b[PSC_VOLTAGE_IN] = 0;
131                 info->R[PSC_VOLTAGE_IN] = -1;
132                 info->m[PSC_VOLTAGE_OUT] = 6720;
133                 info->b[PSC_VOLTAGE_OUT] = 0;
134                 info->R[PSC_VOLTAGE_OUT] = -1;
135         }
136
137         if (config & ADM1275_VIN_VOUT_SELECT)
138                 info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
139         else
140                 info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
141
142         ret = pmbus_do_probe(client, id, info);
143         if (ret)
144                 goto err_mem;
145         return 0;
146
147 err_mem:
148         kfree(info);
149         return ret;
150 }
151
152 static int adm1275_remove(struct i2c_client *client)
153 {
154         const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
155         int ret;
156
157         ret = pmbus_do_remove(client);
158         kfree(info);
159         return ret;
160 }
161
162 static const struct i2c_device_id adm1275_id[] = {
163         {"adm1275", 0},
164         { }
165 };
166 MODULE_DEVICE_TABLE(i2c, adm1275_id);
167
168 static struct i2c_driver adm1275_driver = {
169         .driver = {
170                    .name = "adm1275",
171                    },
172         .probe = adm1275_probe,
173         .remove = adm1275_remove,
174         .id_table = adm1275_id,
175 };
176
177 static int __init adm1275_init(void)
178 {
179         return i2c_add_driver(&adm1275_driver);
180 }
181
182 static void __exit adm1275_exit(void)
183 {
184         i2c_del_driver(&adm1275_driver);
185 }
186
187 MODULE_AUTHOR("Guenter Roeck");
188 MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275");
189 MODULE_LICENSE("GPL");
190 module_init(adm1275_init);
191 module_exit(adm1275_exit);