0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/delay.h>
0011 #include <linux/freezer.h>
0012 #include <linux/fs.h>
0013 #include <linux/jiffies.h>
0014 #include <linux/module.h>
0015 #include <linux/timer.h>
0016 #include <linux/uaccess.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/power_supply.h>
0019
0020 #include <linux/mfd/da9052/da9052.h>
0021 #include <linux/mfd/da9052/pdata.h>
0022 #include <linux/mfd/da9052/reg.h>
0023
0024
0025 #define DA9052_BAT_CUTOFF_VOLT 2800
0026 #define DA9052_BAT_TSH 62000
0027 #define DA9052_BAT_LOW_CAP 4
0028 #define DA9052_AVG_SZ 4
0029 #define DA9052_VC_TBL_SZ 68
0030 #define DA9052_VC_TBL_REF_SZ 3
0031
0032 #define DA9052_ISET_USB_MASK 0x0F
0033 #define DA9052_CHG_USB_ILIM_MASK 0x40
0034 #define DA9052_CHG_LIM_COLS 16
0035
0036 #define DA9052_MEAN(x, y) ((x + y) / 2)
0037
0038 enum charger_type_enum {
0039 DA9052_NOCHARGER = 1,
0040 DA9052_CHARGER,
0041 };
0042
0043 static const u16 da9052_chg_current_lim[2][DA9052_CHG_LIM_COLS] = {
0044 {70, 80, 90, 100, 110, 120, 400, 450,
0045 500, 550, 600, 650, 700, 900, 1100, 1300},
0046 {80, 90, 100, 110, 120, 400, 450, 500,
0047 550, 600, 800, 1000, 1200, 1400, 1600, 1800},
0048 };
0049
0050 static const u16 vc_tbl_ref[3] = {10, 25, 40};
0051
0052 static u32 const vc_tbl[3][68][2] = {
0053
0054 {
0055 {4082, 100}, {4036, 98},
0056 {4020, 96}, {4008, 95},
0057 {3997, 93}, {3983, 91},
0058 {3964, 90}, {3943, 88},
0059 {3926, 87}, {3912, 85},
0060 {3900, 84}, {3890, 82},
0061 {3881, 80}, {3873, 79},
0062 {3865, 77}, {3857, 76},
0063 {3848, 74}, {3839, 73},
0064 {3829, 71}, {3820, 70},
0065 {3811, 68}, {3802, 67},
0066 {3794, 65}, {3785, 64},
0067 {3778, 62}, {3770, 61},
0068 {3763, 59}, {3756, 58},
0069 {3750, 56}, {3744, 55},
0070 {3738, 53}, {3732, 52},
0071 {3727, 50}, {3722, 49},
0072 {3717, 47}, {3712, 46},
0073 {3708, 44}, {3703, 43},
0074 {3700, 41}, {3696, 40},
0075 {3693, 38}, {3691, 37},
0076 {3688, 35}, {3686, 34},
0077 {3683, 32}, {3681, 31},
0078 {3678, 29}, {3675, 28},
0079 {3672, 26}, {3669, 25},
0080 {3665, 23}, {3661, 22},
0081 {3656, 21}, {3651, 19},
0082 {3645, 18}, {3639, 16},
0083 {3631, 15}, {3622, 13},
0084 {3611, 12}, {3600, 10},
0085 {3587, 9}, {3572, 7},
0086 {3548, 6}, {3503, 5},
0087 {3420, 3}, {3268, 2},
0088 {2992, 1}, {2746, 0}
0089 },
0090
0091 {
0092 {4102, 100}, {4065, 98},
0093 {4048, 96}, {4034, 95},
0094 {4021, 93}, {4011, 92},
0095 {4001, 90}, {3986, 88},
0096 {3968, 87}, {3952, 85},
0097 {3938, 84}, {3926, 82},
0098 {3916, 81}, {3908, 79},
0099 {3900, 77}, {3892, 76},
0100 {3883, 74}, {3874, 73},
0101 {3864, 71}, {3855, 70},
0102 {3846, 68}, {3836, 67},
0103 {3827, 65}, {3819, 64},
0104 {3810, 62}, {3801, 61},
0105 {3793, 59}, {3786, 58},
0106 {3778, 56}, {3772, 55},
0107 {3765, 53}, {3759, 52},
0108 {3754, 50}, {3748, 49},
0109 {3743, 47}, {3738, 46},
0110 {3733, 44}, {3728, 43},
0111 {3724, 41}, {3720, 40},
0112 {3716, 38}, {3712, 37},
0113 {3709, 35}, {3706, 34},
0114 {3703, 33}, {3701, 31},
0115 {3698, 30}, {3696, 28},
0116 {3693, 27}, {3690, 25},
0117 {3687, 24}, {3683, 22},
0118 {3680, 21}, {3675, 19},
0119 {3671, 18}, {3666, 17},
0120 {3660, 15}, {3654, 14},
0121 {3647, 12}, {3639, 11},
0122 {3630, 9}, {3621, 8},
0123 {3613, 6}, {3606, 5},
0124 {3597, 4}, {3582, 2},
0125 {3546, 1}, {2747, 0}
0126 },
0127
0128 {
0129 {4114, 100}, {4081, 98},
0130 {4065, 96}, {4050, 95},
0131 {4036, 93}, {4024, 92},
0132 {4013, 90}, {4002, 88},
0133 {3990, 87}, {3976, 85},
0134 {3962, 84}, {3950, 82},
0135 {3939, 81}, {3930, 79},
0136 {3921, 77}, {3912, 76},
0137 {3902, 74}, {3893, 73},
0138 {3883, 71}, {3874, 70},
0139 {3865, 68}, {3856, 67},
0140 {3847, 65}, {3838, 64},
0141 {3829, 62}, {3820, 61},
0142 {3812, 59}, {3803, 58},
0143 {3795, 56}, {3787, 55},
0144 {3780, 53}, {3773, 52},
0145 {3767, 50}, {3761, 49},
0146 {3756, 47}, {3751, 46},
0147 {3746, 44}, {3741, 43},
0148 {3736, 41}, {3732, 40},
0149 {3728, 38}, {3724, 37},
0150 {3720, 35}, {3716, 34},
0151 {3713, 33}, {3710, 31},
0152 {3707, 30}, {3704, 28},
0153 {3701, 27}, {3698, 25},
0154 {3695, 24}, {3691, 22},
0155 {3686, 21}, {3681, 19},
0156 {3676, 18}, {3671, 17},
0157 {3666, 15}, {3661, 14},
0158 {3655, 12}, {3648, 11},
0159 {3640, 9}, {3632, 8},
0160 {3622, 6}, {3616, 5},
0161 {3611, 4}, {3604, 2},
0162 {3594, 1}, {2747, 0}
0163 }
0164 };
0165
0166 struct da9052_battery {
0167 struct da9052 *da9052;
0168 struct power_supply *psy;
0169 struct notifier_block nb;
0170 int charger_type;
0171 int status;
0172 int health;
0173 };
0174
0175 static inline int volt_reg_to_mV(int value)
0176 {
0177 return ((value * 1000) / 512) + 2500;
0178 }
0179
0180 static inline int ichg_reg_to_mA(int value)
0181 {
0182 return (value * 3900) / 1000;
0183 }
0184
0185 static int da9052_read_chgend_current(struct da9052_battery *bat,
0186 int *current_mA)
0187 {
0188 int ret;
0189
0190 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
0191 return -EINVAL;
0192
0193 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_END_REG);
0194 if (ret < 0)
0195 return ret;
0196
0197 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGEND_ICHGEND);
0198
0199 return 0;
0200 }
0201
0202 static int da9052_read_chg_current(struct da9052_battery *bat, int *current_mA)
0203 {
0204 int ret;
0205
0206 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
0207 return -EINVAL;
0208
0209 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_AV_REG);
0210 if (ret < 0)
0211 return ret;
0212
0213 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGAV_ICHGAV);
0214
0215 return 0;
0216 }
0217
0218 static int da9052_bat_check_status(struct da9052_battery *bat, int *status)
0219 {
0220 u8 v[2] = {0, 0};
0221 u8 bat_status;
0222 u8 chg_end;
0223 int ret;
0224 int chg_current;
0225 int chg_end_current;
0226 bool dcinsel;
0227 bool dcindet;
0228 bool vbussel;
0229 bool vbusdet;
0230 bool dc;
0231 bool vbus;
0232
0233 ret = da9052_group_read(bat->da9052, DA9052_STATUS_A_REG, 2, v);
0234 if (ret < 0)
0235 return ret;
0236
0237 bat_status = v[0];
0238 chg_end = v[1];
0239
0240 dcinsel = bat_status & DA9052_STATUSA_DCINSEL;
0241 dcindet = bat_status & DA9052_STATUSA_DCINDET;
0242 vbussel = bat_status & DA9052_STATUSA_VBUSSEL;
0243 vbusdet = bat_status & DA9052_STATUSA_VBUSDET;
0244 dc = dcinsel && dcindet;
0245 vbus = vbussel && vbusdet;
0246
0247
0248 if (dc || vbus) {
0249 bat->charger_type = DA9052_CHARGER;
0250
0251
0252
0253
0254 if ((chg_end & DA9052_STATUSB_CHGEND) != 0) {
0255 ret = da9052_read_chg_current(bat, &chg_current);
0256 if (ret < 0)
0257 return ret;
0258 ret = da9052_read_chgend_current(bat, &chg_end_current);
0259 if (ret < 0)
0260 return ret;
0261
0262 if (chg_current >= chg_end_current)
0263 bat->status = POWER_SUPPLY_STATUS_CHARGING;
0264 else
0265 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
0266 } else {
0267
0268
0269
0270 bat->status = POWER_SUPPLY_STATUS_CHARGING;
0271 }
0272 } else if (dcindet || vbusdet) {
0273 bat->charger_type = DA9052_CHARGER;
0274 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
0275 } else {
0276 bat->charger_type = DA9052_NOCHARGER;
0277 bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
0278 }
0279
0280 if (status != NULL)
0281 *status = bat->status;
0282 return 0;
0283 }
0284
0285 static int da9052_bat_read_volt(struct da9052_battery *bat, int *volt_mV)
0286 {
0287 int volt;
0288
0289 volt = da9052_adc_manual_read(bat->da9052, DA9052_ADC_MAN_MUXSEL_VBAT);
0290 if (volt < 0)
0291 return volt;
0292
0293 *volt_mV = volt_reg_to_mV(volt);
0294
0295 return 0;
0296 }
0297
0298 static int da9052_bat_check_presence(struct da9052_battery *bat, int *illegal)
0299 {
0300 int bat_temp;
0301
0302 bat_temp = da9052_adc_read_temp(bat->da9052);
0303 if (bat_temp < 0)
0304 return bat_temp;
0305
0306 if (bat_temp > DA9052_BAT_TSH)
0307 *illegal = 1;
0308 else
0309 *illegal = 0;
0310
0311 return 0;
0312 }
0313
0314 static int da9052_bat_interpolate(int vbat_lower, int vbat_upper,
0315 int level_lower, int level_upper,
0316 int bat_voltage)
0317 {
0318 int tmp;
0319
0320 tmp = ((level_upper - level_lower) * 1000) / (vbat_upper - vbat_lower);
0321 tmp = level_lower + (((bat_voltage - vbat_lower) * tmp) / 1000);
0322
0323 return tmp;
0324 }
0325
0326 static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
0327 {
0328 int i;
0329
0330 if (adc_temp <= vc_tbl_ref[0])
0331 return 0;
0332
0333 if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1])
0334 return DA9052_VC_TBL_REF_SZ - 1;
0335
0336 for (i = 0; i < DA9052_VC_TBL_REF_SZ - 1; i++) {
0337 if ((adc_temp > vc_tbl_ref[i]) &&
0338 (adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1])))
0339 return i;
0340 if ((adc_temp > DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1]))
0341 && (adc_temp <= vc_tbl_ref[i]))
0342 return i + 1;
0343 }
0344
0345
0346
0347
0348
0349 WARN_ON(1);
0350 return 0;
0351 }
0352
0353 static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity)
0354 {
0355 int adc_temp;
0356 int bat_voltage;
0357 int vbat_lower;
0358 int vbat_upper;
0359 int level_upper;
0360 int level_lower;
0361 int ret;
0362 int flag;
0363 int i = 0;
0364 int j;
0365
0366 ret = da9052_bat_read_volt(bat, &bat_voltage);
0367 if (ret < 0)
0368 return ret;
0369
0370 adc_temp = da9052_adc_read_temp(bat->da9052);
0371 if (adc_temp < 0)
0372 return adc_temp;
0373
0374 i = da9052_determine_vc_tbl_index(adc_temp);
0375
0376 if (bat_voltage >= vc_tbl[i][0][0]) {
0377 *capacity = 100;
0378 return 0;
0379 }
0380 if (bat_voltage <= vc_tbl[i][DA9052_VC_TBL_SZ - 1][0]) {
0381 *capacity = 0;
0382 return 0;
0383 }
0384 flag = 0;
0385
0386 for (j = 0; j < (DA9052_VC_TBL_SZ-1); j++) {
0387 if ((bat_voltage <= vc_tbl[i][j][0]) &&
0388 (bat_voltage >= vc_tbl[i][j + 1][0])) {
0389 vbat_upper = vc_tbl[i][j][0];
0390 vbat_lower = vc_tbl[i][j + 1][0];
0391 level_upper = vc_tbl[i][j][1];
0392 level_lower = vc_tbl[i][j + 1][1];
0393 flag = 1;
0394 break;
0395 }
0396 }
0397 if (!flag)
0398 return -EIO;
0399
0400 *capacity = da9052_bat_interpolate(vbat_lower, vbat_upper, level_lower,
0401 level_upper, bat_voltage);
0402
0403 return 0;
0404 }
0405
0406 static int da9052_bat_check_health(struct da9052_battery *bat, int *health)
0407 {
0408 int ret;
0409 int bat_illegal;
0410 int capacity;
0411
0412 ret = da9052_bat_check_presence(bat, &bat_illegal);
0413 if (ret < 0)
0414 return ret;
0415
0416 if (bat_illegal) {
0417 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
0418 return 0;
0419 }
0420
0421 if (bat->health != POWER_SUPPLY_HEALTH_OVERHEAT) {
0422 ret = da9052_bat_read_capacity(bat, &capacity);
0423 if (ret < 0)
0424 return ret;
0425 if (capacity < DA9052_BAT_LOW_CAP)
0426 bat->health = POWER_SUPPLY_HEALTH_DEAD;
0427 else
0428 bat->health = POWER_SUPPLY_HEALTH_GOOD;
0429 }
0430
0431 *health = bat->health;
0432
0433 return 0;
0434 }
0435
0436 static irqreturn_t da9052_bat_irq(int irq, void *data)
0437 {
0438 struct da9052_battery *bat = data;
0439 int virq;
0440
0441 virq = regmap_irq_get_virq(bat->da9052->irq_data, irq);
0442 irq -= virq;
0443
0444 if (irq == DA9052_IRQ_CHGEND)
0445 bat->status = POWER_SUPPLY_STATUS_FULL;
0446 else
0447 da9052_bat_check_status(bat, NULL);
0448
0449 if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN ||
0450 irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) {
0451 power_supply_changed(bat->psy);
0452 }
0453
0454 return IRQ_HANDLED;
0455 }
0456
0457 static int da9052_USB_current_notifier(struct notifier_block *nb,
0458 unsigned long events, void *data)
0459 {
0460 u8 row;
0461 u8 col;
0462 int *current_mA = data;
0463 int ret;
0464 struct da9052_battery *bat = container_of(nb, struct da9052_battery,
0465 nb);
0466
0467 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
0468 return -EPERM;
0469
0470 ret = da9052_reg_read(bat->da9052, DA9052_CHGBUCK_REG);
0471 if (ret & DA9052_CHG_USB_ILIM_MASK)
0472 return -EPERM;
0473
0474 if (bat->da9052->chip_id == DA9052)
0475 row = 0;
0476 else
0477 row = 1;
0478
0479 if (*current_mA < da9052_chg_current_lim[row][0] ||
0480 *current_mA > da9052_chg_current_lim[row][DA9052_CHG_LIM_COLS - 1])
0481 return -EINVAL;
0482
0483 for (col = 0; col <= DA9052_CHG_LIM_COLS - 1 ; col++) {
0484 if (*current_mA <= da9052_chg_current_lim[row][col])
0485 break;
0486 }
0487
0488 return da9052_reg_update(bat->da9052, DA9052_ISET_REG,
0489 DA9052_ISET_USB_MASK, col);
0490 }
0491
0492 static int da9052_bat_get_property(struct power_supply *psy,
0493 enum power_supply_property psp,
0494 union power_supply_propval *val)
0495 {
0496 int ret;
0497 int illegal;
0498 struct da9052_battery *bat = power_supply_get_drvdata(psy);
0499
0500 ret = da9052_bat_check_presence(bat, &illegal);
0501 if (ret < 0)
0502 return ret;
0503
0504 if (illegal && psp != POWER_SUPPLY_PROP_PRESENT)
0505 return -ENODEV;
0506
0507 switch (psp) {
0508 case POWER_SUPPLY_PROP_STATUS:
0509 ret = da9052_bat_check_status(bat, &val->intval);
0510 break;
0511 case POWER_SUPPLY_PROP_ONLINE:
0512 val->intval =
0513 (bat->charger_type == DA9052_NOCHARGER) ? 0 : 1;
0514 break;
0515 case POWER_SUPPLY_PROP_PRESENT:
0516 ret = da9052_bat_check_presence(bat, &val->intval);
0517 break;
0518 case POWER_SUPPLY_PROP_HEALTH:
0519 ret = da9052_bat_check_health(bat, &val->intval);
0520 break;
0521 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
0522 val->intval = DA9052_BAT_CUTOFF_VOLT * 1000;
0523 break;
0524 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0525 ret = da9052_bat_read_volt(bat, &val->intval);
0526 break;
0527 case POWER_SUPPLY_PROP_CURRENT_AVG:
0528 ret = da9052_read_chg_current(bat, &val->intval);
0529 break;
0530 case POWER_SUPPLY_PROP_CAPACITY:
0531 ret = da9052_bat_read_capacity(bat, &val->intval);
0532 break;
0533 case POWER_SUPPLY_PROP_TEMP:
0534 val->intval = da9052_adc_read_temp(bat->da9052);
0535 ret = val->intval;
0536 break;
0537 case POWER_SUPPLY_PROP_TECHNOLOGY:
0538 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
0539 break;
0540 default:
0541 return -EINVAL;
0542 }
0543 return ret;
0544 }
0545
0546 static enum power_supply_property da9052_bat_props[] = {
0547 POWER_SUPPLY_PROP_STATUS,
0548 POWER_SUPPLY_PROP_ONLINE,
0549 POWER_SUPPLY_PROP_PRESENT,
0550 POWER_SUPPLY_PROP_HEALTH,
0551 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
0552 POWER_SUPPLY_PROP_VOLTAGE_AVG,
0553 POWER_SUPPLY_PROP_CURRENT_AVG,
0554 POWER_SUPPLY_PROP_CAPACITY,
0555 POWER_SUPPLY_PROP_TEMP,
0556 POWER_SUPPLY_PROP_TECHNOLOGY,
0557 };
0558
0559 static struct power_supply_desc psy_desc = {
0560 .name = "da9052-bat",
0561 .type = POWER_SUPPLY_TYPE_BATTERY,
0562 .properties = da9052_bat_props,
0563 .num_properties = ARRAY_SIZE(da9052_bat_props),
0564 .get_property = da9052_bat_get_property,
0565 };
0566
0567 static char *da9052_bat_irqs[] = {
0568 "BATT TEMP",
0569 "DCIN DET",
0570 "DCIN REM",
0571 "VBUS DET",
0572 "VBUS REM",
0573 "CHG END",
0574 };
0575
0576 static int da9052_bat_irq_bits[] = {
0577 DA9052_IRQ_TBAT,
0578 DA9052_IRQ_DCIN,
0579 DA9052_IRQ_DCINREM,
0580 DA9052_IRQ_VBUS,
0581 DA9052_IRQ_VBUSREM,
0582 DA9052_IRQ_CHGEND,
0583 };
0584
0585 static s32 da9052_bat_probe(struct platform_device *pdev)
0586 {
0587 struct da9052_pdata *pdata;
0588 struct da9052_battery *bat;
0589 struct power_supply_config psy_cfg = {};
0590 int ret;
0591 int i;
0592
0593 bat = devm_kzalloc(&pdev->dev, sizeof(struct da9052_battery),
0594 GFP_KERNEL);
0595 if (!bat)
0596 return -ENOMEM;
0597
0598 psy_cfg.drv_data = bat;
0599
0600 bat->da9052 = dev_get_drvdata(pdev->dev.parent);
0601 bat->charger_type = DA9052_NOCHARGER;
0602 bat->status = POWER_SUPPLY_STATUS_UNKNOWN;
0603 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
0604 bat->nb.notifier_call = da9052_USB_current_notifier;
0605
0606 pdata = bat->da9052->dev->platform_data;
0607 if (pdata != NULL && pdata->use_for_apm)
0608 psy_desc.use_for_apm = pdata->use_for_apm;
0609 else
0610 psy_desc.use_for_apm = 1;
0611
0612 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
0613 ret = da9052_request_irq(bat->da9052,
0614 da9052_bat_irq_bits[i], da9052_bat_irqs[i],
0615 da9052_bat_irq, bat);
0616
0617 if (ret != 0) {
0618 dev_err(bat->da9052->dev,
0619 "DA9052 failed to request %s IRQ: %d\n",
0620 da9052_bat_irqs[i], ret);
0621 goto err;
0622 }
0623 }
0624
0625 bat->psy = power_supply_register(&pdev->dev, &psy_desc, &psy_cfg);
0626 if (IS_ERR(bat->psy)) {
0627 ret = PTR_ERR(bat->psy);
0628 goto err;
0629 }
0630
0631 platform_set_drvdata(pdev, bat);
0632 return 0;
0633
0634 err:
0635 while (--i >= 0)
0636 da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat);
0637
0638 return ret;
0639 }
0640 static int da9052_bat_remove(struct platform_device *pdev)
0641 {
0642 int i;
0643 struct da9052_battery *bat = platform_get_drvdata(pdev);
0644
0645 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++)
0646 da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat);
0647
0648 power_supply_unregister(bat->psy);
0649
0650 return 0;
0651 }
0652
0653 static struct platform_driver da9052_bat_driver = {
0654 .probe = da9052_bat_probe,
0655 .remove = da9052_bat_remove,
0656 .driver = {
0657 .name = "da9052-bat",
0658 },
0659 };
0660 module_platform_driver(da9052_bat_driver);
0661
0662 MODULE_DESCRIPTION("DA9052 BAT Device Driver");
0663 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
0664 MODULE_LICENSE("GPL");
0665 MODULE_ALIAS("platform:da9052-bat");