Merge tag 'for-linus-20190524' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / hwmon / pmbus / ucd9200.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Hardware monitoring driver for ucd9200 series Digital PWM System Controllers
4  *
5  * Copyright (C) 2011 Ericsson AB.
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/of_device.h>
11 #include <linux/init.h>
12 #include <linux/err.h>
13 #include <linux/slab.h>
14 #include <linux/i2c.h>
15 #include <linux/pmbus.h>
16 #include "pmbus.h"
17
18 #define UCD9200_PHASE_INFO      0xd2
19 #define UCD9200_DEVICE_ID       0xfd
20
21 enum chips { ucd9200, ucd9220, ucd9222, ucd9224, ucd9240, ucd9244, ucd9246,
22              ucd9248 };
23
24 static const struct i2c_device_id ucd9200_id[] = {
25         {"ucd9200", ucd9200},
26         {"ucd9220", ucd9220},
27         {"ucd9222", ucd9222},
28         {"ucd9224", ucd9224},
29         {"ucd9240", ucd9240},
30         {"ucd9244", ucd9244},
31         {"ucd9246", ucd9246},
32         {"ucd9248", ucd9248},
33         {}
34 };
35 MODULE_DEVICE_TABLE(i2c, ucd9200_id);
36
37 static const struct of_device_id __maybe_unused ucd9200_of_match[] = {
38         {
39                 .compatible = "ti,cd9200",
40                 .data = (void *)ucd9200
41         },
42         {
43                 .compatible = "ti,cd9220",
44                 .data = (void *)ucd9220
45         },
46         {
47                 .compatible = "ti,cd9222",
48                 .data = (void *)ucd9222
49         },
50         {
51                 .compatible = "ti,cd9224",
52                 .data = (void *)ucd9224
53         },
54         {
55                 .compatible = "ti,cd9240",
56                 .data = (void *)ucd9240
57         },
58         {
59                 .compatible = "ti,cd9244",
60                 .data = (void *)ucd9244
61         },
62         {
63                 .compatible = "ti,cd9246",
64                 .data = (void *)ucd9246
65         },
66         {
67                 .compatible = "ti,cd9248",
68                 .data = (void *)ucd9248
69         },
70         { },
71 };
72 MODULE_DEVICE_TABLE(of, ucd9200_of_match);
73
74 static int ucd9200_probe(struct i2c_client *client,
75                          const struct i2c_device_id *id)
76 {
77         u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
78         struct pmbus_driver_info *info;
79         const struct i2c_device_id *mid;
80         enum chips chip;
81         int i, j, ret;
82
83         if (!i2c_check_functionality(client->adapter,
84                                      I2C_FUNC_SMBUS_BYTE_DATA |
85                                      I2C_FUNC_SMBUS_BLOCK_DATA))
86                 return -ENODEV;
87
88         ret = i2c_smbus_read_block_data(client, UCD9200_DEVICE_ID,
89                                         block_buffer);
90         if (ret < 0) {
91                 dev_err(&client->dev, "Failed to read device ID\n");
92                 return ret;
93         }
94         block_buffer[ret] = '\0';
95         dev_info(&client->dev, "Device ID %s\n", block_buffer);
96
97         for (mid = ucd9200_id; mid->name[0]; mid++) {
98                 if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
99                         break;
100         }
101         if (!mid->name[0]) {
102                 dev_err(&client->dev, "Unsupported device\n");
103                 return -ENODEV;
104         }
105
106         if (client->dev.of_node)
107                 chip = (enum chips)of_device_get_match_data(&client->dev);
108         else
109                 chip = id->driver_data;
110
111         if (chip != ucd9200 && chip != mid->driver_data)
112                 dev_notice(&client->dev,
113                            "Device mismatch: Configured %s, detected %s\n",
114                            id->name, mid->name);
115
116         info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
117                             GFP_KERNEL);
118         if (!info)
119                 return -ENOMEM;
120
121         ret = i2c_smbus_read_block_data(client, UCD9200_PHASE_INFO,
122                                         block_buffer);
123         if (ret < 0) {
124                 dev_err(&client->dev, "Failed to read phase information\n");
125                 return ret;
126         }
127
128         /*
129          * Calculate number of configured pages (rails) from PHASE_INFO
130          * register.
131          * Rails have to be sequential, so we can abort after finding
132          * the first unconfigured rail.
133          */
134         info->pages = 0;
135         for (i = 0; i < ret; i++) {
136                 if (!block_buffer[i])
137                         break;
138                 info->pages++;
139         }
140         if (!info->pages) {
141                 dev_err(&client->dev, "No rails configured\n");
142                 return -ENODEV;
143         }
144         dev_info(&client->dev, "%d rails configured\n", info->pages);
145
146         /*
147          * Set PHASE registers on all pages to 0xff to ensure that phase
148          * specific commands will apply to all phases of a given page (rail).
149          * This only affects the READ_IOUT and READ_TEMPERATURE2 registers.
150          * READ_IOUT will return the sum of currents of all phases of a rail,
151          * and READ_TEMPERATURE2 will return the maximum temperature detected
152          * for the the phases of the rail.
153          */
154         for (i = 0; i < info->pages; i++) {
155                 /*
156                  * Setting PAGE & PHASE fails once in a while for no obvious
157                  * reason, so we need to retry a couple of times.
158                  */
159                 for (j = 0; j < 3; j++) {
160                         ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i);
161                         if (ret < 0)
162                                 continue;
163                         ret = i2c_smbus_write_byte_data(client, PMBUS_PHASE,
164                                                         0xff);
165                         if (ret < 0)
166                                 continue;
167                         break;
168                 }
169                 if (ret < 0) {
170                         dev_err(&client->dev,
171                                 "Failed to initialize PHASE registers\n");
172                         return ret;
173                 }
174         }
175         if (info->pages > 1)
176                 i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
177
178         info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
179                         PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
180                         PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
181                         PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
182                         PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP |
183                         PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
184
185         for (i = 1; i < info->pages; i++)
186                 info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
187                         PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
188                         PMBUS_HAVE_POUT |
189                         PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
190
191         /* ucd9240 supports a single fan */
192         if (mid->driver_data == ucd9240)
193                 info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12;
194
195         return pmbus_do_probe(client, mid, info);
196 }
197
198 /* This is the driver that will be inserted */
199 static struct i2c_driver ucd9200_driver = {
200         .driver = {
201                 .name = "ucd9200",
202                 .of_match_table = of_match_ptr(ucd9200_of_match),
203         },
204         .probe = ucd9200_probe,
205         .remove = pmbus_do_remove,
206         .id_table = ucd9200_id,
207 };
208
209 module_i2c_driver(ucd9200_driver);
210
211 MODULE_AUTHOR("Guenter Roeck");
212 MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x");
213 MODULE_LICENSE("GPL");