arm: tegra: pluto: board changes for max77665 charger
[linux-3.10.git] / arch / arm / mach-tegra / board-pluto-sensors.c
1 /*
2  * arch/arm/mach-tegra/board-pluto-sensors.c
3  *
4  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that 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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include <linux/err.h>
20 #include <linux/i2c.h>
21 #include <linux/delay.h>
22 #include <linux/regulator/consumer.h>
23 #include <mach/edp.h>
24 #include <linux/gpio.h>
25 #include <linux/mpu.h>
26 #include <linux/max77665-charger.h>
27 #include <linux/mfd/max77665.h>
28 #include <linux/power/max17042_battery.h>
29 #include <mach/gpio.h>
30 #include <mach/gpio-tegra.h>
31 #include <media/max77665-flash.h>
32 #include <media/imx091.h>
33 #include <media/imx132.h>
34 #include <media/ad5816.h>
35
36 #include <linux/nct1008.h>
37 #include "gpio-names.h"
38 #include "board.h"
39 #include "board-pluto.h"
40 #include "cpu-tegra.h"
41 #include "devices.h"
42 #include "tegra-board-id.h"
43
44 #define CAMERA_FLASH_SYNC_GPIO  TEGRA_GPIO_PBB4
45 #define NTC_10K_TGAIN   0xE6A2
46 #define NTC_10K_TOFF    0x2694
47
48 static struct max77665_muic_platform_data max77665_muic;
49 static struct board_info board_info;
50 static struct max17042_config_data conf_data = {
51         .valrt_thresh = 0xff00,
52         .talrt_thresh = 0xff00,
53         .soc_alrt_thresh = 0xff00,
54         .shdntimer = 0xe000,
55         .design_cap = 0x07d0,
56         .at_rate = 0x0000,
57         .tgain = NTC_10K_TGAIN,
58         .toff = NTC_10K_TOFF,
59         .vempty = 0xACDA,
60         .qrtbl00 = 0x5C80,
61         .qrtbl10 = 0x438C,
62         .qrtbl20 = 0x1198,
63         .qrtbl30 = 0x0E19,
64         .full_soc_thresh = 0x5A00,
65         .rcomp0 = 0x0077,
66         .tcompc0 = 0x1F2A,
67         .ichgt_term = 0x0320,
68         .temp_nom = 0x1400,
69         .temp_lim = 0x2305,
70         .filter_cfg = 0x87A4,
71         .config = 0x2210,
72         .learn_cfg = 0x2606,
73         .misc_cfg = 0x0810,
74         .fullcap =  0x07d0,
75         .fullcapnom = 0x07d0,
76         .lavg_empty = 0x1000,
77         .dqacc = 0x01f4,
78         .dpacc = 0x3200,
79         .fctc = 0x05e0,
80         .kempty0 = 0x0600,
81         .cell_technology = POWER_SUPPLY_TECHNOLOGY_LION,
82         .cell_char_tbl = {
83                 /* Data to be written from 0x80h */
84                 0x9180, 0xA4C0, 0xB6A0, 0xB760, 0xB980, 0xBB30,
85                 0xBBC0, 0xBC50, 0xBD50, 0xBE50, 0xBF80, 0xC290,
86                 0xC470, 0xC7D0, 0xCC40, 0xCFB0,
87                 /* Data to be written from 0x90h */
88                 0x00C0, 0x0200, 0x1C10, 0x0B00, 0x0900, 0x1F00,
89                 0x1F00, 0x23C0, 0x1990, 0x19F0, 0x09A0, 0x0CE0,
90                 0x0BE0, 0x07D0, 0x0990, 0x0990,
91                 /* Data to be written from 0xA0h */
92                 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
93                 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
94                 0x0100, 0x0100, 0x0100, 0x0100,
95         },
96 };
97
98 static struct max17042_platform_data max17042_pdata = {
99         .config_data = &conf_data,
100         .init_data  = NULL,
101         .num_init_data = 0,
102         .enable_por_init = 1, /* Use POR init from Maxim appnote */
103         .enable_current_sense = 1,
104         .r_sns = 0,
105 };
106
107 static struct i2c_board_info max17042_device[] = {
108         {
109                 I2C_BOARD_INFO("max17042", 0x36),
110                 .platform_data = &max17042_pdata,
111         },
112 };
113
114 static struct max77665_f_platform_data pluto_max77665_flash_pdata = {
115         .config         = {
116                 .led_mask               = 3,
117                 .flash_on_torch         = true,
118                 .max_total_current_mA   = 1000,
119                 .max_peak_current_mA    = 600,
120                 },
121         .pinstate       = {
122                 .mask   = 1 << (CAMERA_FLASH_SYNC_GPIO - TEGRA_GPIO_PBB0),
123                 .values = 1 << (CAMERA_FLASH_SYNC_GPIO - TEGRA_GPIO_PBB0)
124                 },
125         .dev_name       = "torch",
126         .gpio_strobe    = CAMERA_FLASH_SYNC_GPIO,
127 };
128
129 static struct max77665_platform_data pluto_max77665_pdata = {
130         .irq_base = 0,
131 };
132
133 static const struct i2c_board_info pluto_i2c_board_info_max77665[] = {
134         {
135                 I2C_BOARD_INFO("max77665", 0x66),
136                 .platform_data = &pluto_max77665_pdata,
137         },
138 };
139
140 static struct max77665_charger_cable maxim_cable[] = {
141         {
142                 .name           = "USB",
143         },
144         {
145                 .name           = "USB-Host",
146         },
147         {
148                 .name           = "TA",
149         },
150         {
151                 .name           = "Fast-charger",
152         },
153         {
154                 .name           = "Slow-charger",
155         },
156         {
157                 .name           = "Charge-downstream",
158         },
159 };
160
161 static struct max77665_charger_plat_data max77665_charger = {
162         .fast_chg_cc = 1500, /* fast charger current*/
163         .term_volt = 3700, /* charger termination voltage */
164         .curr_lim = 1500, /* input current limit */
165         .num_cables = MAX_CABLES,
166         .cables = maxim_cable,
167 };
168
169 /* isl29029 support is provided by isl29028*/
170 static struct i2c_board_info pluto_i2c1_isl_board_info[] = {
171         {
172                 I2C_BOARD_INFO("isl29028", 0x44),
173         }
174 };
175
176 struct pluto_cam_gpio {
177         int gpio;
178         const char *label;
179         int value;
180 };
181
182 static char *pluto_cam_reg_name[] = {
183         "avdd_cam1",            /* Analog VDD 2.7V */
184         "avdd_cam2",            /* Analog VDD 2.7V */
185         "vdd_1v2_cam",          /* Digital VDD 1.2V */
186         "vdd_1v8_cam12",        /* Digital VDDIO 1.8V */
187         "vddio_cam_mb",         /* CAM_I2C PULL-UP VDD 1.8V */
188         "vdd_af_cam1",          /* AF VDD */
189 };
190
191 static struct regulator *pluto_cam_reg[ARRAY_SIZE(pluto_cam_reg_name)];
192
193 static struct balanced_throttle tj_throttle = {
194         .throt_tab_size = 10,
195         .throt_tab = {
196                 {      0, 1000 },
197                 { 640000, 1000 },
198                 { 640000, 1000 },
199                 { 640000, 1000 },
200                 { 640000, 1000 },
201                 { 640000, 1000 },
202                 { 760000, 1000 },
203                 { 760000, 1050 },
204                 {1000000, 1050 },
205                 {1000000, 1100 },
206         },
207 };
208
209 static struct nct1008_platform_data pluto_nct1008_pdata = {
210         .supported_hwrev = true,
211         .ext_range = true,
212         .conv_rate = 0x08,
213         .offset = 80, /* 4 * 20C. Bug 844025 - 1C for device accuracies */
214         .shutdown_ext_limit = 90, /* C */
215         .shutdown_local_limit = 120, /* C */
216
217         /* Thermal Throttling */
218         .passive = {
219                 .create_cdev = (struct thermal_cooling_device *(*)(void *))
220                                 balanced_throttle_register,
221                 .cdev_data = &tj_throttle,
222                 .trip_temp = 80000,
223                 .tc1 = 0,
224                 .tc2 = 1,
225                 .passive_delay = 2000,
226         }
227 };
228
229 static struct i2c_board_info pluto_i2c4_nct1008_board_info[] = {
230         {
231                 I2C_BOARD_INFO("nct1008", 0x4C),
232                 .platform_data = &pluto_nct1008_pdata,
233                 .irq = -1,
234         }
235 };
236
237 static int pluto_imx091_power_on(struct device *dev)
238 {
239         int i;
240
241         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
242                 if (!pluto_cam_reg[i]) {
243                         pluto_cam_reg[i] = regulator_get(dev,
244                                         pluto_cam_reg_name[i]);
245                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
246                                 pr_err("%s: didn't get regulator #%d: %ld\n",
247                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
248                                 goto reg_alloc_fail;
249                         }
250                 }
251                 regulator_enable(pluto_cam_reg[i]);
252         }
253
254         gpio_direction_output(CAM_RSTN, 0);
255         gpio_direction_output(CAM_GPIO1, 1);
256         gpio_direction_output(CAM_RSTN, 1);
257
258         mdelay(1);
259
260         return 0;
261
262 reg_alloc_fail:
263
264         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
265                 if (pluto_cam_reg[i]) {
266                         regulator_put(pluto_cam_reg[i]);
267                         pluto_cam_reg[i] = NULL;
268                 }
269         }
270         pr_info("%s fail\n", __func__);
271
272         return -ENODEV;
273 }
274
275 static int pluto_imx091_power_off(struct device *dev)
276 {
277         int i;
278
279         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
280                 if (pluto_cam_reg[i]) {
281                         regulator_disable(pluto_cam_reg[i]);
282                         regulator_put(pluto_cam_reg[i]);
283                         pluto_cam_reg[i] = NULL;
284                 }
285         }
286
287         return 0;
288 }
289
290 static int pluto_imx132_power_on(struct device *dev)
291 {
292         int i;
293
294         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
295                 if (!pluto_cam_reg[i]) {
296                         pluto_cam_reg[i] = regulator_get(dev,
297                                         pluto_cam_reg_name[i]);
298                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
299                                 pr_err("%s: didn't get regulator #%d: %ld\n",
300                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
301                                 goto reg_alloc_fail;
302                         }
303                 }
304                 regulator_enable(pluto_cam_reg[i]);
305         }
306
307         gpio_direction_output(CAM_RSTN, 0);
308         gpio_direction_output(CAM_GPIO2, 1);
309         gpio_direction_output(CAM_RSTN, 1);
310
311         mdelay(1);
312
313         return 0;
314
315 reg_alloc_fail:
316         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
317                 if (pluto_cam_reg[i]) {
318                         regulator_put(pluto_cam_reg[i]);
319                         pluto_cam_reg[i] = NULL;
320                 }
321         }
322
323         return -ENODEV;
324 }
325
326
327 static int pluto_imx132_power_off(struct device *dev)
328 {
329         int i;
330
331         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
332                 if (pluto_cam_reg[i]) {
333                         regulator_disable(pluto_cam_reg[i]);
334                         regulator_put(pluto_cam_reg[i]);
335                         pluto_cam_reg[i] = NULL;
336                 }
337         }
338
339         return 0;
340 }
341
342 struct imx091_platform_data pluto_imx091_data = {
343         .power_on = pluto_imx091_power_on,
344         .power_off = pluto_imx091_power_off,
345 };
346
347 struct imx132_platform_data pluto_imx132_data = {
348         .power_on = pluto_imx132_power_on,
349         .power_off = pluto_imx132_power_off,
350 };
351
352 static struct ad5816_platform_data pluto_ad5816_pdata = {
353         .cfg            = 0,
354         .num            = 0,
355         .sync           = 0,
356         .dev_name       = "focuser",
357 };
358
359 static struct i2c_board_info pluto_i2c_board_info_e1625[] = {
360         {
361                 I2C_BOARD_INFO("imx091", 0x10),
362                 .platform_data = &pluto_imx091_data,
363         },
364         {
365                 I2C_BOARD_INFO("imx132", 0x36),
366                 .platform_data = &pluto_imx132_data,
367         },
368         {
369                 I2C_BOARD_INFO("ad5816", 0x0E),
370                 .platform_data = &pluto_ad5816_pdata,
371         },
372 };
373
374 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
375         {                                                       \
376                 .gpio = _gpio,                                  \
377                 .label = _label,                                \
378                 .value = _value,                                \
379         }
380 static struct pluto_cam_gpio pluto_cam_gpio_data[] = {
381         [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 1),
382         [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 1),
383         [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
384         [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
385         [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
386         [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
387 };
388
389 static int pluto_camera_init(void)
390 {
391         int ret;
392         int i;
393
394         pr_debug("%s: ++\n", __func__);
395
396         for (i = 0; i < ARRAY_SIZE(pluto_cam_gpio_data); i++) {
397                 ret = gpio_request(pluto_cam_gpio_data[i].gpio,
398                                 pluto_cam_gpio_data[i].label);
399                 if (ret < 0) {
400                         pr_err("%s: gpio_request failed for gpio #%d\n",
401                                 __func__, i);
402                         goto fail_free_gpio;
403                 }
404                 gpio_direction_output(pluto_cam_gpio_data[i].gpio,
405                                         pluto_cam_gpio_data[i].value);
406                 gpio_export(pluto_cam_gpio_data[i].gpio, false);
407         }
408
409         i2c_register_board_info(2, pluto_i2c_board_info_e1625,
410                 ARRAY_SIZE(pluto_i2c_board_info_e1625));
411
412         return 0;
413
414 fail_free_gpio:
415         while (i--)
416                 gpio_free(pluto_cam_gpio_data[i].gpio);
417         return ret;
418 }
419
420 /* MPU board file definition */
421 static struct mpu_platform_data mpu_gyro_data = {
422         .int_config     = 0x10,
423         .level_shifter  = 0,
424         .orientation    = MPU_GYRO_ORIENTATION,
425         .sec_slave_type = SECONDARY_SLAVE_TYPE_NONE,
426         .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
427                            0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
428 };
429
430 static struct mpu_platform_data mpu_compass_data = {
431         .orientation    = MPU_COMPASS_ORIENTATION,
432         .sec_slave_type = SECONDARY_SLAVE_TYPE_NONE,
433 };
434
435 static struct i2c_board_info __initdata inv_mpu_i2c0_board_info[] = {
436         {
437                 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
438                 .platform_data = &mpu_gyro_data,
439         },
440         {
441                 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
442                 .platform_data = &mpu_compass_data,
443         },
444 };
445
446 static void mpuirq_init(void)
447 {
448         int ret = 0;
449         int i = 0;
450
451         pr_info("*** MPU START *** mpuirq_init...\n");
452
453         /* MPU-IRQ assignment */
454         ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
455         if (ret < 0) {
456                 pr_err("%s: gpio_request failed %d\n", __func__, ret);
457                 return;
458         }
459
460         ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
461         if (ret < 0) {
462                 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
463                 gpio_free(MPU_GYRO_IRQ_GPIO);
464                 return;
465         }
466         pr_info("*** MPU END *** mpuirq_init...\n");
467
468         inv_mpu_i2c0_board_info[i++].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
469 #if MPU_COMPASS_IRQ_GPIO
470         inv_mpu_i2c0_board_info[i++].irq = gpio_to_irq(MPU_COMPASS_IRQ_GPIO);
471 #endif
472         i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c0_board_info,
473                 ARRAY_SIZE(inv_mpu_i2c0_board_info));
474 }
475
476 static int pluto_nct1008_init(void)
477 {
478         int nct1008_port = -1;
479         int ret = 0;
480
481 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
482         if (board_info.board_id == BOARD_E1580) {
483                 nct1008_port = TEGRA_GPIO_PX6;
484         } else {
485                 nct1008_port = TEGRA_GPIO_PX6;
486                 pr_err("Warning: nct alert port assumed TEGRA_GPIO_PX6 for unknown pluto board id E%d\n",
487                        board_info.board_id);
488         }
489 #else
490         /* pluto + AP30 interposer has SPI2_CS0 gpio */
491         nct1008_port = TEGRA_GPIO_PX3;
492 #endif
493
494         if (nct1008_port >= 0) {
495 #ifdef CONFIG_TEGRA_EDP_LIMITS
496                 const struct tegra_edp_limits *cpu_edp_limits;
497                 int cpu_edp_limits_size;
498                 int i;
499
500                 /* edp capping */
501                 tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
502
503                 if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
504                         BUG();
505
506                 for (i = 0; i < cpu_edp_limits_size-1; i++) {
507                         pluto_nct1008_pdata.active[i].create_cdev =
508                                 (struct thermal_cooling_device *(*)(void *))
509                                         edp_cooling_device_create;
510                         pluto_nct1008_pdata.active[i].cdev_data = (void *)i;
511                         pluto_nct1008_pdata.active[i].trip_temp =
512                                 cpu_edp_limits[i].temperature * 1000;
513                         pluto_nct1008_pdata.active[i].hysteresis = 1000;
514                 }
515                 pluto_nct1008_pdata.active[i].create_cdev = NULL;
516 #endif
517
518                 pluto_i2c4_nct1008_board_info[0].irq = gpio_to_irq(nct1008_port);
519                 pr_info("%s: pluto nct1008 irq %d", __func__, pluto_i2c4_nct1008_board_info[0].irq);
520
521                 ret = gpio_request(nct1008_port, "temp_alert");
522                 if (ret < 0)
523                         return ret;
524
525                 ret = gpio_direction_input(nct1008_port);
526                 if (ret < 0) {
527                         pr_info("%s: calling gpio_free(nct1008_port)", __func__);
528                         gpio_free(nct1008_port);
529                 }
530         }
531
532         /* pluto has thermal sensor on GEN1-I2C i.e. instance 0 */
533         i2c_register_board_info(0, pluto_i2c4_nct1008_board_info,
534                 ARRAY_SIZE(pluto_i2c4_nct1008_board_info));
535
536         return ret;
537 }
538
539 #ifdef CONFIG_TEGRA_SKIN_THROTTLE
540 static int tegra_skin_match(struct thermal_zone_device *thz, void *data)
541 {
542         return strcmp((char *)data, thz->type) == 0;
543 }
544
545 static int tegra_skin_get_temp(void *data, long *temp)
546 {
547         struct thermal_zone_device *thz;
548
549         thz = thermal_zone_device_find(data, tegra_skin_match);
550
551         if (!thz || thz->ops->get_temp(thz, temp))
552                 *temp = 25000;
553
554         return 0;
555 }
556
557 static struct therm_est_data skin_data = {
558         .toffset = 9793,
559         .polling_period = 1100,
560         .ndevs = 2,
561         .devs = {
562                         {
563                                 .dev_data = "nct_ext",
564                                 .get_temp = tegra_skin_get_temp,
565                                 .coeffs = {
566                                         2, 1, 1, 1,
567                                         1, 1, 1, 1,
568                                         1, 1, 1, 0,
569                                         1, 1, 0, 0,
570                                         0, 0, -1, -7
571                                 },
572                         },
573                         {
574                                 .dev_data = "nct_int",
575                                 .get_temp = tegra_skin_get_temp,
576                                 .coeffs = {
577                                         -11, -7, -5, -3,
578                                         -3, -2, -1, 0,
579                                         0, 0, 1, 1,
580                                         1, 2, 2, 3,
581                                         4, 6, 11, 18
582                                 },
583                         },
584         },
585         .trip_temp = 43000,
586         .tc1 = 1,
587         .tc2 = 15,
588         .passive_delay = 15000,
589 };
590
591 static struct balanced_throttle skin_throttle = {
592         .throt_tab_size = 6,
593         .throt_tab = {
594                 { 640000, 1200 },
595                 { 640000, 1200 },
596                 { 760000, 1200 },
597                 { 760000, 1200 },
598                 {1000000, 1200 },
599                 {1000000, 1200 },
600         },
601 };
602
603 static int __init pluto_skin_init(void)
604 {
605         struct thermal_cooling_device *skin_cdev;
606
607         skin_cdev = balanced_throttle_register(&skin_throttle);
608
609         skin_data.cdev = skin_cdev;
610         tegra_skin_therm_est_device.dev.platform_data = &skin_data;
611         platform_device_register(&tegra_skin_therm_est_device);
612
613         return 0;
614 }
615 late_initcall(pluto_skin_init);
616 #endif
617
618 int __init pluto_sensors_init(void)
619 {
620         struct platform_device *pd;
621         struct platform_device *charger_pd, *muic_pd;
622         int err;
623
624         tegra_get_board_info(&board_info);
625
626         pr_debug("%s: ++\n", __func__);
627         pluto_camera_init();
628
629         err = pluto_nct1008_init();
630         if (err)
631                 return err;
632
633         i2c_register_board_info(0, pluto_i2c1_isl_board_info,
634                                 ARRAY_SIZE(pluto_i2c1_isl_board_info));
635         mpuirq_init();
636
637         max77665_muic.irq_base = 0;
638         muic_pd = kmemdup(&max77665_muic, sizeof(max77665_muic), GFP_KERNEL);
639         if (muic_pd == NULL) {
640                 pr_err("%s failed to allocate memory\n", __func__);
641                 return -ENOMEM;
642         }
643
644         pluto_max77665_pdata.muic_platform_data.pdata = muic_pd;
645         pluto_max77665_pdata.muic_platform_data.size = sizeof(*muic_pd);
646
647         charger_pd = kmemdup(&max77665_charger, sizeof(max77665_charger),
648                         GFP_KERNEL);
649         if (charger_pd == NULL) {
650                 pr_err("%s failed to allocate memory\n", __func__);
651                 return -ENOMEM;
652         }
653
654         pluto_max77665_pdata.charger_platform_data.pdata = charger_pd;
655         pluto_max77665_pdata.charger_platform_data.size = sizeof(*charger_pd);
656
657         pd = kmemdup(&pluto_max77665_flash_pdata,
658                         sizeof(pluto_max77665_flash_pdata), GFP_KERNEL);
659         if (pd == NULL) {
660                 pr_err("%s failed to allocate memory\n", __func__);
661                 return -ENOMEM;
662         }
663
664         pluto_max77665_pdata.flash_platform_data.pdata = pd;
665         pluto_max77665_pdata.flash_platform_data.size = sizeof(*pd);
666
667         err = i2c_register_board_info(4, pluto_i2c_board_info_max77665,
668                 ARRAY_SIZE(pluto_i2c_board_info_max77665));
669
670         if (err)
671                 pr_err("%s: platform device register failed.\n", __func__);
672
673         i2c_register_board_info(0, max17042_device,
674                                 ARRAY_SIZE(max17042_device));
675
676         return 0;
677 }