ARM: tegra: ardbeg: add power monitor devices
[linux-3.10.git] / arch / arm / mach-tegra / board-ardbeg-powermon.c
1 /*
2  * arch/arm/mach-tegra/board-ardbeg-powermon.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19
20 #include <linux/i2c.h>
21 #include <linux/ina219.h>
22 #include <linux/platform_data/ina230.h>
23 #include <linux/i2c/pca954x.h>
24
25 #include "board.h"
26 #include "board-ardbeg.h"
27
28 #define PRECISION_MULTIPLIER_ARDBEG     1000
29
30 /* unused rail */
31 enum {
32         UNUSED_RAIL,
33 };
34
35 /* following rails are present on Ardbeg */
36 /* rails on i2c2_1 */
37 enum {
38         VDD_SYS_BAT,
39         VDD_RTC_LDO5,
40         VDD_3V3A_SMPS1_2,
41         VDD_SOC_SMPS1_2,
42         VDD_SYS_BUCKCPU,
43         VDD_CPU_BUCKCPU,
44         VDD_1V8A_SMPS3,
45         VDD_1V8B_SMPS9,
46         VDD_GPU_BUCKGPU,
47         VDD_1V35_SMPS6,
48         VDD_3V3A_SMPS1_2_2,
49         VDD_3V3B_SMPS9,
50         VDD_LCD_1V8B_DIS,
51         VDD_1V05_SMPS8,
52 };
53
54 /* rails on i2c2_2 */
55 enum {
56         VDD_SYS_BL,
57         AVDD_1V05_LDO2,
58 };
59
60 static struct ina219_platform_data power_mon_info_0[] = {
61         /* All unused INA219 devices use below data */
62         [UNUSED_RAIL] = {
63                 .calibration_data = 0x369c,
64                 .power_lsb = 3.051979018 * PRECISION_MULTIPLIER_ARDBEG,
65                 .rail_name = "unused_rail",
66                 .divisor = 20,
67                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
68         },
69 };
70
71 /* following are power monitor parameters for Ardbeg */
72 static struct ina230_platform_data power_mon_info_1[] = {
73         [VDD_SYS_BAT] = {
74                 .calibration_data  = 0x1366,
75                 .power_lsb = 2.577527185 * PRECISION_MULTIPLIER_ARDBEG,
76                 .rail_name = "VDD_SYS_BAT",
77                 .divisor = 25,
78                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
79         },
80
81         [VDD_RTC_LDO5] = {
82                 .calibration_data  = 0x7FFF,
83                 .power_lsb = 0.078127384 * PRECISION_MULTIPLIER_ARDBEG,
84                 .rail_name = "VDD_RTC_LDO5",
85                 .divisor = 25,
86                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
87         },
88
89         [VDD_3V3A_SMPS1_2] = {
90                 .calibration_data  = 0x4759,
91                 .power_lsb = 1.401587736 * PRECISION_MULTIPLIER_ARDBEG,
92                 .rail_name = "VDD_3V3A_SMPS1_2",
93                 .divisor = 25,
94                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
95         },
96
97         [VDD_SOC_SMPS1_2] = {
98                 .calibration_data  = 0x7FFF,
99                 .power_lsb = 3.906369213 * PRECISION_MULTIPLIER_ARDBEG,
100                 .rail_name = "VDD_SOC_SMPS1_2",
101                 .divisor = 25,
102                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
103         },
104
105         [VDD_SYS_BUCKCPU] = {
106                 .calibration_data  = 0x1AC5,
107                 .power_lsb = 1.867795126 * PRECISION_MULTIPLIER_ARDBEG,
108                 .rail_name = "VDD_SYS_BUCKCPU",
109                 .divisor = 25,
110                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
111         },
112
113         [VDD_CPU_BUCKCPU] = {
114                 .calibration_data  = 0x2ECF,
115                 .power_lsb = 10.68179922 * PRECISION_MULTIPLIER_ARDBEG,
116                 .rail_name = "VDD_CPU_BUCKCPU",
117                 .divisor = 25,
118                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
119         },
120
121         [VDD_1V8A_SMPS3] = {
122                 .calibration_data  = 0x5BA7,
123                 .power_lsb = 0.545539786 * PRECISION_MULTIPLIER_ARDBEG,
124                 .rail_name = "VDD_1V8A_SMPS3",
125                 .divisor = 25,
126                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
127         },
128
129         [VDD_1V8B_SMPS9] = {
130                 .calibration_data  = 0x50B4,
131                 .power_lsb = 0.309777348 * PRECISION_MULTIPLIER_ARDBEG,
132                 .rail_name = "VDD_1V8B_SMPS9",
133                 .divisor = 25,
134                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
135         },
136
137         [VDD_GPU_BUCKGPU] = {
138                 .calibration_data  = 0x369C,
139                 .power_lsb = 9.155937053 * PRECISION_MULTIPLIER_ARDBEG,
140                 .rail_name = "VDD_GPU_BUCKGPU",
141                 .divisor = 25,
142                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
143         },
144
145         [VDD_1V35_SMPS6] = {
146                 .calibration_data  = 0x7FFF,
147                 .power_lsb = 3.906369213 * PRECISION_MULTIPLIER_ARDBEG,
148                 .rail_name = "VDD_1V35_SMPS6",
149                 .divisor = 25,
150                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
151         },
152
153         /* following rail is duplicate of VDD_3V3A_SMPS1_2 hence mark unused */
154         [VDD_3V3A_SMPS1_2_2] = {
155                 .calibration_data  = 0x4759,
156                 .power_lsb = 1.401587736 * PRECISION_MULTIPLIER_ARDBEG,
157                 .rail_name = "unused_rail",
158                 .divisor = 25,
159                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
160         },
161
162         [VDD_3V3B_SMPS9] = {
163                 .calibration_data  = 0x3269,
164                 .power_lsb = 0.198372724 * PRECISION_MULTIPLIER_ARDBEG,
165                 .rail_name = "VDD_3V3B_SMPS9",
166                 .divisor = 25,
167                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
168         },
169
170         [VDD_LCD_1V8B_DIS] = {
171                 .calibration_data  = 0x7FFF,
172                 .power_lsb = 0.039063692 * PRECISION_MULTIPLIER_ARDBEG,
173                 .rail_name = "VDD_LCD_1V8B_DIS",
174                 .divisor = 25,
175                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
176         },
177
178         [VDD_1V05_SMPS8] = {
179                 .calibration_data  = 0x7FFF,
180                 .power_lsb = 0.130212307 * PRECISION_MULTIPLIER_ARDBEG,
181                 .rail_name = "VDD_1V05_SMPS8",
182                 .divisor = 25,
183                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
184         },
185 };
186
187 static struct ina230_platform_data power_mon_info_2[] = {
188         [VDD_SYS_BL] = {
189                 .calibration_data  = 0x1A29,
190                 .power_lsb = 0.63710119 * PRECISION_MULTIPLIER_ARDBEG,
191                 .rail_name = "VDD_SYS_BL",
192                 .divisor = 25,
193                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
194         },
195
196         [AVDD_1V05_LDO2] = {
197                 .calibration_data  = 0x7FFF,
198                 .power_lsb = 0.390636921 * PRECISION_MULTIPLIER_ARDBEG,
199                 .rail_name = "AVDD_1V05_LDO2",
200                 .divisor = 25,
201                 .precision_multiplier = PRECISION_MULTIPLIER_ARDBEG,
202         },
203 };
204
205 /* i2c addresses of rails present on Ardbeg */
206 /* addresses on i2c2_0 */
207 enum {
208         INA_I2C_2_0_ADDR_40,
209         INA_I2C_2_0_ADDR_41,
210         INA_I2C_2_0_ADDR_42,
211         INA_I2C_2_0_ADDR_43,
212 };
213
214 /* addresses on i2c2_1 */
215 enum {
216         INA_I2C_2_1_ADDR_40,
217         INA_I2C_2_1_ADDR_41,
218         INA_I2C_2_1_ADDR_42,
219         INA_I2C_2_1_ADDR_43,
220         INA_I2C_2_1_ADDR_44,
221         INA_I2C_2_1_ADDR_45,
222         INA_I2C_2_1_ADDR_46,
223         INA_I2C_2_1_ADDR_47,
224         INA_I2C_2_1_ADDR_48,
225         INA_I2C_2_1_ADDR_49,
226         INA_I2C_2_1_ADDR_4B,
227         INA_I2C_2_1_ADDR_4C,
228         INA_I2C_2_1_ADDR_4E,
229         INA_I2C_2_1_ADDR_4F,
230 };
231
232 /* addresses on i2c2_2 */
233 enum {
234         INA_I2C_2_2_ADDR_49,
235         INA_I2C_2_2_ADDR_4C,
236 };
237
238 static struct i2c_board_info ardbeg_i2c2_0_ina219_board_info[] = {
239         [INA_I2C_2_0_ADDR_40] = {
240                 I2C_BOARD_INFO("ina219", 0x40),
241                 .platform_data = &power_mon_info_0[UNUSED_RAIL],
242                 .irq = -1,
243         },
244
245         [INA_I2C_2_0_ADDR_41] = {
246                 I2C_BOARD_INFO("ina219", 0x41),
247                 .platform_data = &power_mon_info_0[UNUSED_RAIL],
248                 .irq = -1,
249         },
250
251         [INA_I2C_2_0_ADDR_42] = {
252                 I2C_BOARD_INFO("ina219", 0x42),
253                 .platform_data = &power_mon_info_0[UNUSED_RAIL],
254                 .irq = -1,
255         },
256
257         [INA_I2C_2_0_ADDR_43] = {
258                 I2C_BOARD_INFO("ina219", 0x43),
259                 .platform_data = &power_mon_info_0[UNUSED_RAIL],
260                 .irq = -1,
261         },
262 };
263
264 static struct i2c_board_info ardbeg_i2c2_1_ina230_board_info[] = {
265         [INA_I2C_2_1_ADDR_40] = {
266                 I2C_BOARD_INFO("ina230", 0x40),
267                 .platform_data = &power_mon_info_1[VDD_SYS_BAT],
268                 .irq = -1,
269         },
270
271         [INA_I2C_2_1_ADDR_41] = {
272                 I2C_BOARD_INFO("ina230", 0x41),
273                 .platform_data = &power_mon_info_1[VDD_RTC_LDO5],
274                 .irq = -1,
275         },
276
277         [INA_I2C_2_1_ADDR_42] = {
278                 I2C_BOARD_INFO("ina230", 0x42),
279                 .platform_data = &power_mon_info_1[VDD_3V3A_SMPS1_2],
280                 .irq = -1,
281         },
282
283         [INA_I2C_2_1_ADDR_43] = {
284                 I2C_BOARD_INFO("ina230", 0x43),
285                 .platform_data = &power_mon_info_1[VDD_SOC_SMPS1_2],
286                 .irq = -1,
287         },
288
289         [INA_I2C_2_1_ADDR_44] = {
290                 I2C_BOARD_INFO("ina230", 0x44),
291                 .platform_data = &power_mon_info_1[VDD_SYS_BUCKCPU],
292                 .irq = -1,
293         },
294
295         [INA_I2C_2_1_ADDR_45] = {
296                 I2C_BOARD_INFO("ina230", 0x45),
297                 .platform_data = &power_mon_info_1[VDD_CPU_BUCKCPU],
298                 .irq = -1,
299         },
300
301         [INA_I2C_2_1_ADDR_46] = {
302                 I2C_BOARD_INFO("ina230", 0x46),
303                 .platform_data = &power_mon_info_1[VDD_1V8A_SMPS3],
304                 .irq = -1,
305         },
306
307         [INA_I2C_2_1_ADDR_47] = {
308                 I2C_BOARD_INFO("ina230", 0x47),
309                 .platform_data = &power_mon_info_1[VDD_1V8B_SMPS9],
310                 .irq = -1,
311         },
312
313         [INA_I2C_2_1_ADDR_48] = {
314                 I2C_BOARD_INFO("ina230", 0x48),
315                 .platform_data = &power_mon_info_1[VDD_GPU_BUCKGPU],
316                 .irq = -1,
317         },
318
319         [INA_I2C_2_1_ADDR_49] = {
320                 I2C_BOARD_INFO("ina230", 0x49),
321                 .platform_data = &power_mon_info_1[VDD_1V35_SMPS6],
322                 .irq = -1,
323         },
324
325         [INA_I2C_2_1_ADDR_4B] = {
326                 I2C_BOARD_INFO("ina230", 0x4B),
327                 .platform_data = &power_mon_info_1[VDD_3V3A_SMPS1_2_2],
328                 .irq = -1,
329         },
330
331         [INA_I2C_2_1_ADDR_4C] = {
332                 I2C_BOARD_INFO("ina230", 0x4C),
333                 .platform_data = &power_mon_info_1[VDD_3V3B_SMPS9],
334                 .irq = -1,
335         },
336
337         [INA_I2C_2_1_ADDR_4E] = {
338                 I2C_BOARD_INFO("ina230", 0x4E),
339                 .platform_data = &power_mon_info_1[VDD_LCD_1V8B_DIS],
340                 .irq = -1,
341         },
342
343         [INA_I2C_2_1_ADDR_4F] = {
344                 I2C_BOARD_INFO("ina230", 0x4F),
345                 .platform_data = &power_mon_info_1[VDD_1V05_SMPS8],
346                 .irq = -1,
347         },
348 };
349
350 static struct i2c_board_info ardbeg_i2c2_2_ina230_board_info[] = {
351         [INA_I2C_2_2_ADDR_49] = {
352                 I2C_BOARD_INFO("ina230", 0x49),
353                 .platform_data = &power_mon_info_2[VDD_SYS_BL],
354                 .irq = -1,
355         },
356
357         [INA_I2C_2_2_ADDR_4C] = {
358                 I2C_BOARD_INFO("ina230", 0x4C),
359                 .platform_data = &power_mon_info_2[AVDD_1V05_LDO2],
360                 .irq = -1,
361         },
362
363 };
364
365 static struct pca954x_platform_mode ardbeg_pca954x_modes[] = {
366         { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, },
367         { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, },
368         { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, },
369         { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, },
370 };
371
372 static struct pca954x_platform_data ardbeg_pca954x_data = {
373         .modes    = ardbeg_pca954x_modes,
374         .num_modes      = ARRAY_SIZE(ardbeg_pca954x_modes),
375 };
376
377 static const struct i2c_board_info ardbeg_i2c2_board_info[] = {
378         {
379                 I2C_BOARD_INFO("pca9546", 0x71),
380                 .platform_data = &ardbeg_pca954x_data,
381         },
382 };
383
384 int __init ardbeg_pmon_init(void)
385 {
386         i2c_register_board_info(1, ardbeg_i2c2_board_info,
387                 ARRAY_SIZE(ardbeg_i2c2_board_info));
388
389         i2c_register_board_info(PCA954x_I2C_BUS0,
390                         ardbeg_i2c2_0_ina219_board_info,
391                         ARRAY_SIZE(ardbeg_i2c2_0_ina219_board_info));
392
393         i2c_register_board_info(PCA954x_I2C_BUS1,
394                         ardbeg_i2c2_1_ina230_board_info,
395                         ARRAY_SIZE(ardbeg_i2c2_1_ina230_board_info));
396
397         i2c_register_board_info(PCA954x_I2C_BUS2,
398                         ardbeg_i2c2_2_ina230_board_info,
399                         ARRAY_SIZE(ardbeg_i2c2_2_ina230_board_info));
400
401         return 0;
402 }
403