Lynx framebuffers multidomain implementation.
[linux/elbrus.git] / drivers / misc / i2c_p2pmc.c
blob06abde5c97acebafed157e49e13a1d3b60f206f7
1 /*
2 * i2c_p2pmc.c - Support i2c p2pmc device.
4 * Copyright (C) 2013 Evgeny Kravtsunov <kravtsunov_e@mcst.ru>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 #include <linux/i2c.h>
25 #include <linux/hwmon.h>
26 #include <linux/hwmon-sysfs.h>
27 #include <linux/err.h>
28 #include <linux/sysfs.h>
29 #include <linux/kernel.h>
31 #define I2C_P2PMC_WRITE_OP 0x80
33 #define I2C_P2PMC_REG_ADDR_0 0x0
34 #define I2C_P2PMC_REG_ADDR_1 0x1
35 #define I2C_P2PMC_REG_DATA_0 0x2
36 #define I2C_P2PMC_REG_DATA_1 0x3
37 #define I2C_P2PMC_REG_DATA_2 0x4
38 #define I2C_P2PMC_REG_DATA_3 0x5
39 #define I2C_P2PMC_REG_MASK 0x6
41 #define I2C_P2PMC_ADDR_BYTES 2
42 #define I2C_P2PMC_DATA_BYTES 4
43 #define I2C_P2PMC_MASK_BYTES 1
45 #define I2C_P2PMC_SIZE (I2C_P2PMC_ADDR_BYTES + \
46 I2C_P2PMC_DATA_BYTES + \
47 I2C_P2PMC_MASK_BYTES)
49 #define I2C_MAX_BUFFER_SIZE 64
51 /* Internal address of PMC regs */
52 #define I2C_PMC_L_P_STATE_CNTRL_REG 0x9008
53 #define I2C_PMC_L_TEMP_RG_CUR_REG_0 0x9020
54 #define I2C_PMC_L_TEMP_RG_CUR_REG_1 0x9024
56 /* Moortec temperature sensor values */
57 #define PMC_MOORTEC_TEMP_VALID 0x1000
58 #define PMC_MOORTEC_TEMP_VALUE_MASK 0xfff
59 #define PMC_MOORTEC_TEMP_K 63
60 #define PMC_MOORTEC_TEMP_VALUE_SHIFT 12
62 struct i2c_p2pmc_data {
63 u8 address_0;
64 u8 address_1;
65 u8 data_0;
66 u8 data_1;
67 u8 data_2;
68 u8 data_3;
69 u8 bmask;
70 u8 dbuffer[I2C_MAX_BUFFER_SIZE];
73 /* sysfs */
74 static ssize_t i2c_p2pmc_addr_read(struct device *dev,
75 struct device_attribute *attr, char *buf)
77 struct i2c_client *client = to_i2c_client(dev);
78 u32 addr;
79 u32 addr0;
80 u32 addr1;
81 struct i2c_p2pmc_data *data;
83 data = i2c_get_clientdata(client);
84 addr0 = (u32)(data->address_0);
85 addr0 <<= 8;
86 addr1 = (u32)(data->address_1);
87 addr = addr0 + addr1;
89 return sprintf(buf, "%d\n", addr);
92 static ssize_t i2c_p2pmc_addr_write(struct device *dev,
93 struct device_attribute *attr, const char *buf, size_t count)
95 struct i2c_client *client = to_i2c_client(dev);
96 unsigned long address;
97 struct i2c_p2pmc_data *data;
99 data = i2c_get_clientdata(client);
101 if ((strict_strtoul(buf, 10, &address) < 0))
102 return -EINVAL;
104 data->address_0 = (address >> 8) & 0xFF;
105 data->address_1 = address & 0xFF;
107 return count;
110 static ssize_t i2c_p2pmc_data_read(struct device *dev,
111 struct device_attribute *attr, char *buf)
113 struct i2c_client *client = to_i2c_client(dev);
114 u32 dvalue;
115 u32 dvalue0;
116 u32 dvalue1;
117 u32 dvalue2;
118 u32 dvalue3;
119 struct i2c_p2pmc_data *data;
121 data = i2c_get_clientdata(client);
122 dvalue0 = (u32)(data->data_0);
123 dvalue0 <<= 24;
124 dvalue1 = (u32)(data->data_1);
125 dvalue1 <<= 16;
126 dvalue2 = (u32)(data->data_2);
127 dvalue2 <<= 8;
128 dvalue3 = (u32)(data->data_3);
129 dvalue = dvalue3 + dvalue2 + dvalue1 + dvalue0;
131 return sprintf(buf, "%d\n", dvalue);
134 static ssize_t i2c_p2pmc_data_write(struct device *dev,
135 struct device_attribute *attr, const char *buf, size_t count)
137 struct i2c_client *client = to_i2c_client(dev);
138 unsigned long val;
139 struct i2c_p2pmc_data *data;
141 data = i2c_get_clientdata(client);
142 if ((strict_strtoul(buf, 10, &val) < 0))
143 return -EINVAL;
145 data->data_0 = (val >> 24) & 0xFF;
146 data->data_1 = (val >> 16) & 0xFF;
147 data->data_2 = (val >> 8) & 0xFF;
148 data->data_3 = val & 0xFF;
150 return count;
153 static ssize_t i2c_p2pmc_mask_read(struct device *dev,
154 struct device_attribute *attr, char *buf)
156 struct i2c_client *client = to_i2c_client(dev);
157 s32 mask;
158 struct i2c_p2pmc_data *data;
160 data = i2c_get_clientdata(client);
161 mask = (s32)(data->bmask);
163 return sprintf(buf, "%d\n", mask);
166 static ssize_t i2c_p2pmc_mask_write(struct device *dev,
167 struct device_attribute *attr, const char *buf, size_t count)
169 struct i2c_client *client = to_i2c_client(dev);
170 unsigned long mask;
171 struct i2c_p2pmc_data *data;
173 data = i2c_get_clientdata(client);
174 if ((strict_strtoul(buf, 10, &mask) < 0)) {
175 return -EINVAL;
178 data->bmask = mask & 0xFF;
179 return count;
182 static s32 i2c_p2pmc_do_read(struct device *dev, unsigned short pmcaddr)
184 struct i2c_client *client = to_i2c_client(dev);
185 s32 ret;
186 u32 dvalue;
187 u32 dvalue0;
188 u32 dvalue1;
189 u32 dvalue2;
190 u32 dvalue3;
191 struct i2c_p2pmc_data *data;
193 data = i2c_get_clientdata(client);
195 if (pmcaddr == 0) {
196 /* Get preset addr and data values and write them to target */
197 data->dbuffer[0] = data->address_0;
198 data->dbuffer[1] = data->address_1;
199 } else {
200 data->dbuffer[0] = (pmcaddr >> 8) & 0xFF;
201 data->dbuffer[1] = pmcaddr & 0xFF;
204 ret = i2c_smbus_write_block_data(client,
205 I2C_P2PMC_REG_ADDR_0 & (~I2C_P2PMC_WRITE_OP),
207 data->dbuffer);
208 if (ret < 0) {
209 printk(KERN_ERR "Failed to write addr to slave\n");
210 return ret;
213 ret = i2c_smbus_read_i2c_block_data(client, I2C_P2PMC_REG_DATA_0,
214 4, data->dbuffer);
215 if (ret < 0) {
216 printk(KERN_ERR "Failed to do reading ret = %d\n", ret);
217 return ret;
220 data->data_0 = data->dbuffer[0];
221 data->data_1 = data->dbuffer[1];
222 data->data_2 = data->dbuffer[2];
223 data->data_3 = data->dbuffer[3];
225 dvalue0 = (u32)(data->dbuffer[0]);
226 dvalue0 <<= 24;
227 dvalue1 = (u32)(data->dbuffer[1]);
228 dvalue1 <<= 16;
229 dvalue2 = (u32)(data->dbuffer[2]);
230 dvalue2 <<= 8;
231 dvalue3 = (u32)(data->dbuffer[3]);
232 dvalue = dvalue3 + dvalue2 + dvalue1 + dvalue0;
234 return (s32) dvalue;
237 static ssize_t i2c_p2pmc_read_pmcaddr(struct device *dev,
238 struct device_attribute *attr, char *buf)
240 s32 ret;
242 ret = i2c_p2pmc_do_read(dev, 0);
243 if (ret < 0)
244 return sprintf(buf, "Error\n");
245 else
246 return sprintf(buf, "%d\n", ret);
249 static ssize_t i2c_p2pmc_pstate_read(struct device *dev,
250 struct device_attribute *attr, char *buf)
252 s32 ret;
254 ret = i2c_p2pmc_do_read(dev, I2C_PMC_L_P_STATE_CNTRL_REG);
255 if (ret < 0)
256 return sprintf(buf, "Error\n");
257 else
258 return sprintf(buf, "%d\n", ret);
261 static ssize_t i2c_p2pmc_temp0_read(struct device *dev,
262 struct device_attribute *attr, char *buf)
264 s32 ret;
265 u32 temp;
266 u32 frac;
268 ret = i2c_p2pmc_do_read(dev, I2C_PMC_L_TEMP_RG_CUR_REG_0);
269 if (ret < 0) {
270 return sprintf(buf, "Error\n");
271 } else {
272 temp = (u32) ret;
273 if (temp & PMC_MOORTEC_TEMP_VALID) {
274 temp &= PMC_MOORTEC_TEMP_VALUE_MASK;
275 frac = (temp * 233) & PMC_MOORTEC_TEMP_VALUE_MASK;
276 temp = ((temp * 233) >> PMC_MOORTEC_TEMP_VALUE_SHIFT) -
277 PMC_MOORTEC_TEMP_K;
279 return sprintf(buf, "%d.%d\n", temp, frac);
281 return sprintf(buf, "Bad value\n");
285 static ssize_t i2c_p2pmc_temp1_read(struct device *dev,
286 struct device_attribute *attr, char *buf)
288 s32 ret;
289 u32 temp;
290 u32 frac;
292 ret = i2c_p2pmc_do_read(dev, I2C_PMC_L_TEMP_RG_CUR_REG_1);
293 if (ret < 0) {
294 return sprintf(buf, "Error\n");
295 } else {
296 temp = (u32) ret;
297 if (temp & PMC_MOORTEC_TEMP_VALID) {
298 temp &= PMC_MOORTEC_TEMP_VALUE_MASK;
299 frac = (temp * 233) & PMC_MOORTEC_TEMP_VALUE_MASK;
300 temp = ((temp * 233) >> PMC_MOORTEC_TEMP_VALUE_SHIFT) -
301 PMC_MOORTEC_TEMP_K;
303 return sprintf(buf, "%d.%d\n", temp, frac);
305 return sprintf(buf, "Bad value\n");
309 static DEVICE_ATTR(data, S_IRWXU, i2c_p2pmc_data_read, i2c_p2pmc_data_write);
310 static DEVICE_ATTR(address, S_IRWXU, i2c_p2pmc_addr_read, i2c_p2pmc_addr_write);
311 static DEVICE_ATTR(mask, S_IRWXU, i2c_p2pmc_mask_read, i2c_p2pmc_mask_write);
312 static DEVICE_ATTR(read, S_IRUSR, i2c_p2pmc_read_pmcaddr, NULL);
313 static DEVICE_ATTR(pstate, S_IRUSR, i2c_p2pmc_pstate_read, NULL);
314 static DEVICE_ATTR(temp0, S_IRUSR, i2c_p2pmc_temp0_read, NULL);
315 static DEVICE_ATTR(temp1, S_IRUSR, i2c_p2pmc_temp1_read, NULL);
317 static struct attribute *i2c_p2pmc_attributes[] = {
318 &dev_attr_data.attr,
319 &dev_attr_address.attr,
320 &dev_attr_mask.attr,
321 &dev_attr_read.attr,
322 &dev_attr_pstate.attr,
323 &dev_attr_temp0.attr,
324 &dev_attr_temp1.attr,
325 NULL
328 static const struct attribute_group i2c_p2pmc_attr_group = {
329 .attrs = i2c_p2pmc_attributes,
332 static int i2c_p2pmc_probe(struct i2c_client *client,
333 const struct i2c_device_id *id)
335 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
336 struct i2c_p2pmc_data *data;
337 int err = 0;
339 if (!i2c_check_functionality(adapter, (I2C_FUNC_SMBUS_BYTE |
340 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_10BIT_ADDR)))
341 return -EIO;
343 data = kzalloc(sizeof(struct i2c_p2pmc_data), GFP_KERNEL);
344 if (!data)
345 return -ENOMEM;
347 i2c_set_clientdata(client, data);
349 err = sysfs_create_group(&client->dev.kobj, &i2c_p2pmc_attr_group);
350 if (err) {
351 kfree(data);
352 return err;
355 return 0;
358 static int i2c_p2pmc_remove(struct i2c_client *client)
360 struct i2c_p2pmc_data *data;
362 data = i2c_get_clientdata(client);
363 if (data) {
364 sysfs_remove_group(&client->dev.kobj, &i2c_p2pmc_attr_group);
365 kfree(data);
367 return 0;
370 static const struct i2c_device_id i2c_p2pmc_id[] = {
371 { "i2c_p2pmc", 0 },
374 MODULE_DEVICE_TABLE(i2c, i2c_p2pmc_id);
376 static struct i2c_driver i2c_p2pmc_driver = {
377 .driver = {
378 .name = "i2c_p2pmc",
380 .probe = i2c_p2pmc_probe,
381 .remove = i2c_p2pmc_remove,
382 .id_table = i2c_p2pmc_id,
385 static int __init i2c_p2pmc_init(void)
387 return i2c_add_driver(&i2c_p2pmc_driver);
390 static void __exit i2c_p2pmc_exit(void)
392 i2c_del_driver(&i2c_p2pmc_driver);
395 MODULE_AUTHOR("Evgeny Kravtsunov <kravtsunov_e@mcst.ru>");
396 MODULE_DESCRIPTION("i2c p2pmc device driver");
397 MODULE_LICENSE("GPL");
399 module_init(i2c_p2pmc_init);
400 module_exit(i2c_p2pmc_exit);