linux/drivers/mfd/da9052-core.c
<<
>>
Prefs
   1/*
   2 * Device access for Dialog DA9052 PMICs.
   3 *
   4 * Copyright(c) 2011 Dialog Semiconductor Ltd.
   5 *
   6 * Author: David Dajun Chen <dchen@diasemi.com>
   7 *
   8 *  This program is free software; you can redistribute  it and/or modify it
   9 *  under  the terms of  the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the  License, or (at your
  11 *  option) any later version.
  12 */
  13
  14#include <linux/device.h>
  15#include <linux/delay.h>
  16#include <linux/input.h>
  17#include <linux/interrupt.h>
  18#include <linux/irq.h>
  19#include <linux/mfd/core.h>
  20#include <linux/slab.h>
  21#include <linux/module.h>
  22
  23#include <linux/mfd/da9052/da9052.h>
  24#include <linux/mfd/da9052/pdata.h>
  25#include <linux/mfd/da9052/reg.h>
  26
  27#define DA9052_NUM_IRQ_REGS             4
  28#define DA9052_IRQ_MASK_POS_1           0x01
  29#define DA9052_IRQ_MASK_POS_2           0x02
  30#define DA9052_IRQ_MASK_POS_3           0x04
  31#define DA9052_IRQ_MASK_POS_4           0x08
  32#define DA9052_IRQ_MASK_POS_5           0x10
  33#define DA9052_IRQ_MASK_POS_6           0x20
  34#define DA9052_IRQ_MASK_POS_7           0x40
  35#define DA9052_IRQ_MASK_POS_8           0x80
  36
  37static bool da9052_reg_readable(struct device *dev, unsigned int reg)
  38{
  39        switch (reg) {
  40        case DA9052_PAGE0_CON_REG:
  41        case DA9052_STATUS_A_REG:
  42        case DA9052_STATUS_B_REG:
  43        case DA9052_STATUS_C_REG:
  44        case DA9052_STATUS_D_REG:
  45        case DA9052_EVENT_A_REG:
  46        case DA9052_EVENT_B_REG:
  47        case DA9052_EVENT_C_REG:
  48        case DA9052_EVENT_D_REG:
  49        case DA9052_FAULTLOG_REG:
  50        case DA9052_IRQ_MASK_A_REG:
  51        case DA9052_IRQ_MASK_B_REG:
  52        case DA9052_IRQ_MASK_C_REG:
  53        case DA9052_IRQ_MASK_D_REG:
  54        case DA9052_CONTROL_A_REG:
  55        case DA9052_CONTROL_B_REG:
  56        case DA9052_CONTROL_C_REG:
  57        case DA9052_CONTROL_D_REG:
  58        case DA9052_PDDIS_REG:
  59        case DA9052_INTERFACE_REG:
  60        case DA9052_RESET_REG:
  61        case DA9052_GPIO_0_1_REG:
  62        case DA9052_GPIO_2_3_REG:
  63        case DA9052_GPIO_4_5_REG:
  64        case DA9052_GPIO_6_7_REG:
  65        case DA9052_GPIO_14_15_REG:
  66        case DA9052_ID_0_1_REG:
  67        case DA9052_ID_2_3_REG:
  68        case DA9052_ID_4_5_REG:
  69        case DA9052_ID_6_7_REG:
  70        case DA9052_ID_8_9_REG:
  71        case DA9052_ID_10_11_REG:
  72        case DA9052_ID_12_13_REG:
  73        case DA9052_ID_14_15_REG:
  74        case DA9052_ID_16_17_REG:
  75        case DA9052_ID_18_19_REG:
  76        case DA9052_ID_20_21_REG:
  77        case DA9052_SEQ_STATUS_REG:
  78        case DA9052_SEQ_A_REG:
  79        case DA9052_SEQ_B_REG:
  80        case DA9052_SEQ_TIMER_REG:
  81        case DA9052_BUCKA_REG:
  82        case DA9052_BUCKB_REG:
  83        case DA9052_BUCKCORE_REG:
  84        case DA9052_BUCKPRO_REG:
  85        case DA9052_BUCKMEM_REG:
  86        case DA9052_BUCKPERI_REG:
  87        case DA9052_LDO1_REG:
  88        case DA9052_LDO2_REG:
  89        case DA9052_LDO3_REG:
  90        case DA9052_LDO4_REG:
  91        case DA9052_LDO5_REG:
  92        case DA9052_LDO6_REG:
  93        case DA9052_LDO7_REG:
  94        case DA9052_LDO8_REG:
  95        case DA9052_LDO9_REG:
  96        case DA9052_LDO10_REG:
  97        case DA9052_SUPPLY_REG:
  98        case DA9052_PULLDOWN_REG:
  99        case DA9052_CHGBUCK_REG:
 100        case DA9052_WAITCONT_REG:
 101        case DA9052_ISET_REG:
 102        case DA9052_BATCHG_REG:
 103        case DA9052_CHG_CONT_REG:
 104        case DA9052_INPUT_CONT_REG:
 105        case DA9052_CHG_TIME_REG:
 106        case DA9052_BBAT_CONT_REG:
 107        case DA9052_BOOST_REG:
 108        case DA9052_LED_CONT_REG:
 109        case DA9052_LEDMIN123_REG:
 110        case DA9052_LED1_CONF_REG:
 111        case DA9052_LED2_CONF_REG:
 112        case DA9052_LED3_CONF_REG:
 113        case DA9052_LED1CONT_REG:
 114        case DA9052_LED2CONT_REG:
 115        case DA9052_LED3CONT_REG:
 116        case DA9052_LED_CONT_4_REG:
 117        case DA9052_LED_CONT_5_REG:
 118        case DA9052_ADC_MAN_REG:
 119        case DA9052_ADC_CONT_REG:
 120        case DA9052_ADC_RES_L_REG:
 121        case DA9052_ADC_RES_H_REG:
 122        case DA9052_VDD_RES_REG:
 123        case DA9052_VDD_MON_REG:
 124        case DA9052_ICHG_AV_REG:
 125        case DA9052_ICHG_THD_REG:
 126        case DA9052_ICHG_END_REG:
 127        case DA9052_TBAT_RES_REG:
 128        case DA9052_TBAT_HIGHP_REG:
 129        case DA9052_TBAT_HIGHN_REG:
 130        case DA9052_TBAT_LOW_REG:
 131        case DA9052_T_OFFSET_REG:
 132        case DA9052_ADCIN4_RES_REG:
 133        case DA9052_AUTO4_HIGH_REG:
 134        case DA9052_AUTO4_LOW_REG:
 135        case DA9052_ADCIN5_RES_REG:
 136        case DA9052_AUTO5_HIGH_REG:
 137        case DA9052_AUTO5_LOW_REG:
 138        case DA9052_ADCIN6_RES_REG:
 139        case DA9052_AUTO6_HIGH_REG:
 140        case DA9052_AUTO6_LOW_REG:
 141        case DA9052_TJUNC_RES_REG:
 142        case DA9052_TSI_CONT_A_REG:
 143        case DA9052_TSI_CONT_B_REG:
 144        case DA9052_TSI_X_MSB_REG:
 145        case DA9052_TSI_Y_MSB_REG:
 146        case DA9052_TSI_LSB_REG:
 147        case DA9052_TSI_Z_MSB_REG:
 148        case DA9052_COUNT_S_REG:
 149        case DA9052_COUNT_MI_REG:
 150        case DA9052_COUNT_H_REG:
 151        case DA9052_COUNT_D_REG:
 152        case DA9052_COUNT_MO_REG:
 153        case DA9052_COUNT_Y_REG:
 154        case DA9052_ALARM_MI_REG:
 155        case DA9052_ALARM_H_REG:
 156        case DA9052_ALARM_D_REG:
 157        case DA9052_ALARM_MO_REG:
 158        case DA9052_ALARM_Y_REG:
 159        case DA9052_SECOND_A_REG:
 160        case DA9052_SECOND_B_REG:
 161        case DA9052_SECOND_C_REG:
 162        case DA9052_SECOND_D_REG:
 163        case DA9052_PAGE1_CON_REG:
 164                return true;
 165        default:
 166                return false;
 167        }
 168}
 169
 170static bool da9052_reg_writeable(struct device *dev, unsigned int reg)
 171{
 172        switch (reg) {
 173        case DA9052_PAGE0_CON_REG:
 174        case DA9052_EVENT_A_REG:
 175        case DA9052_EVENT_B_REG:
 176        case DA9052_EVENT_C_REG:
 177        case DA9052_EVENT_D_REG:
 178        case DA9052_IRQ_MASK_A_REG:
 179        case DA9052_IRQ_MASK_B_REG:
 180        case DA9052_IRQ_MASK_C_REG:
 181        case DA9052_IRQ_MASK_D_REG:
 182        case DA9052_CONTROL_A_REG:
 183        case DA9052_CONTROL_B_REG:
 184        case DA9052_CONTROL_C_REG:
 185        case DA9052_CONTROL_D_REG:
 186        case DA9052_PDDIS_REG:
 187        case DA9052_RESET_REG:
 188        case DA9052_GPIO_0_1_REG:
 189        case DA9052_GPIO_2_3_REG:
 190        case DA9052_GPIO_4_5_REG:
 191        case DA9052_GPIO_6_7_REG:
 192        case DA9052_GPIO_14_15_REG:
 193        case DA9052_ID_0_1_REG:
 194        case DA9052_ID_2_3_REG:
 195        case DA9052_ID_4_5_REG:
 196        case DA9052_ID_6_7_REG:
 197        case DA9052_ID_8_9_REG:
 198        case DA9052_ID_10_11_REG:
 199        case DA9052_ID_12_13_REG:
 200        case DA9052_ID_14_15_REG:
 201        case DA9052_ID_16_17_REG:
 202        case DA9052_ID_18_19_REG:
 203        case DA9052_ID_20_21_REG:
 204        case DA9052_SEQ_STATUS_REG:
 205        case DA9052_SEQ_A_REG:
 206        case DA9052_SEQ_B_REG:
 207        case DA9052_SEQ_TIMER_REG:
 208        case DA9052_BUCKA_REG:
 209        case DA9052_BUCKB_REG:
 210        case DA9052_BUCKCORE_REG:
 211        case DA9052_BUCKPRO_REG:
 212        case DA9052_BUCKMEM_REG:
 213        case DA9052_BUCKPERI_REG:
 214        case DA9052_LDO1_REG:
 215        case DA9052_LDO2_REG:
 216        case DA9052_LDO3_REG:
 217        case DA9052_LDO4_REG:
 218        case DA9052_LDO5_REG:
 219        case DA9052_LDO6_REG:
 220        case DA9052_LDO7_REG:
 221        case DA9052_LDO8_REG:
 222        case DA9052_LDO9_REG:
 223        case DA9052_LDO10_REG:
 224        case DA9052_SUPPLY_REG:
 225        case DA9052_PULLDOWN_REG:
 226        case DA9052_CHGBUCK_REG:
 227        case DA9052_WAITCONT_REG:
 228        case DA9052_ISET_REG:
 229        case DA9052_BATCHG_REG:
 230        case DA9052_CHG_CONT_REG:
 231        case DA9052_INPUT_CONT_REG:
 232        case DA9052_BBAT_CONT_REG:
 233        case DA9052_BOOST_REG:
 234        case DA9052_LED_CONT_REG:
 235        case DA9052_LEDMIN123_REG:
 236        case DA9052_LED1_CONF_REG:
 237        case DA9052_LED2_CONF_REG:
 238        case DA9052_LED3_CONF_REG:
 239        case DA9052_LED1CONT_REG:
 240        case DA9052_LED2CONT_REG:
 241        case DA9052_LED3CONT_REG:
 242        case DA9052_LED_CONT_4_REG:
 243        case DA9052_LED_CONT_5_REG:
 244        case DA9052_ADC_MAN_REG:
 245        case DA9052_ADC_CONT_REG:
 246        case DA9052_ADC_RES_L_REG:
 247        case DA9052_ADC_RES_H_REG:
 248        case DA9052_VDD_RES_REG:
 249        case DA9052_VDD_MON_REG:
 250        case DA9052_ICHG_THD_REG:
 251        case DA9052_ICHG_END_REG:
 252        case DA9052_TBAT_HIGHP_REG:
 253        case DA9052_TBAT_HIGHN_REG:
 254        case DA9052_TBAT_LOW_REG:
 255        case DA9052_T_OFFSET_REG:
 256        case DA9052_AUTO4_HIGH_REG:
 257        case DA9052_AUTO4_LOW_REG:
 258        case DA9052_AUTO5_HIGH_REG:
 259        case DA9052_AUTO5_LOW_REG:
 260        case DA9052_AUTO6_HIGH_REG:
 261        case DA9052_AUTO6_LOW_REG:
 262        case DA9052_TSI_CONT_A_REG:
 263        case DA9052_TSI_CONT_B_REG:
 264        case DA9052_COUNT_S_REG:
 265        case DA9052_COUNT_MI_REG:
 266        case DA9052_COUNT_H_REG:
 267        case DA9052_COUNT_D_REG:
 268        case DA9052_COUNT_MO_REG:
 269        case DA9052_COUNT_Y_REG:
 270        case DA9052_ALARM_MI_REG:
 271        case DA9052_ALARM_H_REG:
 272        case DA9052_ALARM_D_REG:
 273        case DA9052_ALARM_MO_REG:
 274        case DA9052_ALARM_Y_REG:
 275        case DA9052_PAGE1_CON_REG:
 276                return true;
 277        default:
 278                return false;
 279        }
 280}
 281
 282static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
 283{
 284        switch (reg) {
 285        case DA9052_STATUS_A_REG:
 286        case DA9052_STATUS_B_REG:
 287        case DA9052_STATUS_C_REG:
 288        case DA9052_STATUS_D_REG:
 289        case DA9052_EVENT_A_REG:
 290        case DA9052_EVENT_B_REG:
 291        case DA9052_EVENT_C_REG:
 292        case DA9052_EVENT_D_REG:
 293        case DA9052_FAULTLOG_REG:
 294        case DA9052_CHG_TIME_REG:
 295        case DA9052_ADC_RES_L_REG:
 296        case DA9052_ADC_RES_H_REG:
 297        case DA9052_VDD_RES_REG:
 298        case DA9052_ICHG_AV_REG:
 299        case DA9052_TBAT_RES_REG:
 300        case DA9052_ADCIN4_RES_REG:
 301        case DA9052_ADCIN5_RES_REG:
 302        case DA9052_ADCIN6_RES_REG:
 303        case DA9052_TJUNC_RES_REG:
 304        case DA9052_TSI_X_MSB_REG:
 305        case DA9052_TSI_Y_MSB_REG:
 306        case DA9052_TSI_LSB_REG:
 307        case DA9052_TSI_Z_MSB_REG:
 308        case DA9052_COUNT_S_REG:
 309        case DA9052_COUNT_MI_REG:
 310        case DA9052_COUNT_H_REG:
 311        case DA9052_COUNT_D_REG:
 312        case DA9052_COUNT_MO_REG:
 313        case DA9052_COUNT_Y_REG:
 314        case DA9052_ALARM_MI_REG:
 315                return true;
 316        default:
 317                return false;
 318        }
 319}
 320
 321/*
 322 * TBAT look-up table is computed from the R90 reg (8 bit register)
 323 * reading as below. The battery temperature is in milliCentigrade
 324 * TBAT = (1/(t1+1/298) - 273) * 1000 mC
 325 * where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255))
 326 * Default values are R25 = 10e3, B = 3380, ITBAT = 50e-6
 327 * Example:
 328 * R25=10E3, B=3380, ITBAT=50e-6, ADCVAL=62d calculates
 329 * TBAT = 20015 mili degrees Centrigrade
 330 *
 331*/
 332static const int32_t tbat_lookup[255] = {
 333        183258, 144221, 124334, 111336, 101826, 94397, 88343, 83257,
 334        78889, 75071, 71688, 68656, 65914, 63414, 61120, 59001,
 335        570366, 55204, 53490, 51881, 50364, 48931, 47574, 46285,
 336        45059, 43889, 42772, 41703, 40678, 39694, 38748, 37838,
 337        36961, 36115, 35297, 34507, 33743, 33002, 32284, 31588,
 338        30911, 30254, 29615, 28994, 28389, 27799, 27225, 26664,
 339        26117, 25584, 25062, 24553, 24054, 23567, 23091, 22624,
 340        22167, 21719, 21281, 20851, 20429, 20015, 19610, 19211,
 341        18820, 18436, 18058, 17688, 17323, 16965, 16612, 16266,
 342        15925, 15589, 15259, 14933, 14613, 14298, 13987, 13681,
 343        13379, 13082, 12788, 12499, 12214, 11933, 11655, 11382,
 344        11112, 10845, 10582, 10322, 10066, 9812, 9562, 9315,
 345        9071, 8830, 8591, 8356, 8123, 7893, 7665, 7440,
 346        7218, 6998, 6780, 6565, 6352, 6141, 5933, 5726,
 347        5522, 5320, 5120, 4922, 4726, 4532, 4340, 4149,
 348        3961, 3774, 3589, 3406, 3225, 3045, 2867, 2690,
 349        2516, 2342, 2170, 2000, 1831, 1664, 1498, 1334,
 350        1171, 1009, 849, 690, 532, 376, 221, 67,
 351        -84, -236, -386, -535, -683, -830, -975, -1119,
 352        -1263, -1405, -1546, -1686, -1825, -1964, -2101, -2237,
 353        -2372, -2506, -2639, -2771, -2902, -3033, -3162, -3291,
 354        -3418, -3545, -3671, -3796, -3920, -4044, -4166, -4288,
 355        -4409, -4529, -4649, -4767, -4885, -5002, -5119, -5235,
 356        -5349, -5464, -5577, -5690, -5802, -5913, -6024, -6134,
 357        -6244, -6352, -6461, -6568, -6675, -6781, -6887, -6992,
 358        -7096, -7200, -7303, -7406, -7508, -7609, -7710, -7810,
 359        -7910, -8009, -8108, -8206, -8304, -8401, -8497, -8593,
 360        -8689, -8784, -8878, -8972, -9066, -9159, -9251, -9343,
 361        -9435, -9526, -9617, -9707, -9796, -9886, -9975, -10063,
 362        -10151, -10238, -10325, -10412, -10839, -10923, -11007, -11090,
 363        -11173, -11256, -11338, -11420, -11501, -11583, -11663, -11744,
 364        -11823, -11903, -11982
 365};
 366
 367static const u8 chan_mux[DA9052_ADC_VBBAT + 1] = {
 368        [DA9052_ADC_VDDOUT]     = DA9052_ADC_MAN_MUXSEL_VDDOUT,
 369        [DA9052_ADC_ICH]        = DA9052_ADC_MAN_MUXSEL_ICH,
 370        [DA9052_ADC_TBAT]       = DA9052_ADC_MAN_MUXSEL_TBAT,
 371        [DA9052_ADC_VBAT]       = DA9052_ADC_MAN_MUXSEL_VBAT,
 372        [DA9052_ADC_IN4]        = DA9052_ADC_MAN_MUXSEL_AD4,
 373        [DA9052_ADC_IN5]        = DA9052_ADC_MAN_MUXSEL_AD5,
 374        [DA9052_ADC_IN6]        = DA9052_ADC_MAN_MUXSEL_AD6,
 375        [DA9052_ADC_VBBAT]      = DA9052_ADC_MAN_MUXSEL_VBBAT
 376};
 377
 378int da9052_adc_manual_read(struct da9052 *da9052, unsigned char channel)
 379{
 380        int ret;
 381        unsigned short calc_data;
 382        unsigned short data;
 383        unsigned char mux_sel;
 384
 385        if (channel > DA9052_ADC_VBBAT)
 386                return -EINVAL;
 387
 388        mutex_lock(&da9052->auxadc_lock);
 389
 390        /* Channel gets activated on enabling the Conversion bit */
 391        mux_sel = chan_mux[channel] | DA9052_ADC_MAN_MAN_CONV;
 392
 393        ret = da9052_reg_write(da9052, DA9052_ADC_MAN_REG, mux_sel);
 394        if (ret < 0)
 395                goto err;
 396
 397        /* Wait for an interrupt */
 398        if (!wait_for_completion_timeout(&da9052->done,
 399                                         msecs_to_jiffies(500))) {
 400                dev_err(da9052->dev,
 401                        "timeout waiting for ADC conversion interrupt\n");
 402                ret = -ETIMEDOUT;
 403                goto err;
 404        }
 405
 406        ret = da9052_reg_read(da9052, DA9052_ADC_RES_H_REG);
 407        if (ret < 0)
 408                goto err;
 409
 410        calc_data = (unsigned short)ret;
 411        data = calc_data << 2;
 412
 413        ret = da9052_reg_read(da9052, DA9052_ADC_RES_L_REG);
 414        if (ret < 0)
 415                goto err;
 416
 417        calc_data = (unsigned short)(ret & DA9052_ADC_RES_LSB);
 418        data |= calc_data;
 419
 420        ret = data;
 421
 422err:
 423        mutex_unlock(&da9052->auxadc_lock);
 424        return ret;
 425}
 426EXPORT_SYMBOL_GPL(da9052_adc_manual_read);
 427
 428static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data)
 429{
 430        struct da9052 *da9052 = irq_data;
 431
 432        complete(&da9052->done);
 433
 434        return IRQ_HANDLED;
 435}
 436
 437int da9052_adc_read_temp(struct da9052 *da9052)
 438{
 439        int tbat;
 440
 441        tbat = da9052_reg_read(da9052, DA9052_TBAT_RES_REG);
 442        if (tbat <= 0)
 443                return tbat;
 444
 445        /* ARRAY_SIZE check is not needed since TBAT is a 8-bit register */
 446        return tbat_lookup[tbat - 1];
 447}
 448EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
 449
 450static struct resource da9052_rtc_resource = {
 451        .name = "ALM",
 452        .start = DA9052_IRQ_ALARM,
 453        .end   = DA9052_IRQ_ALARM,
 454        .flags = IORESOURCE_IRQ,
 455};
 456
 457static struct resource da9052_onkey_resource = {
 458        .name = "ONKEY",
 459        .start = DA9052_IRQ_NONKEY,
 460        .end   = DA9052_IRQ_NONKEY,
 461        .flags = IORESOURCE_IRQ,
 462};
 463
 464static struct resource da9052_bat_resources[] = {
 465        {
 466                .name = "BATT TEMP",
 467                .start = DA9052_IRQ_TBAT,
 468                .end   = DA9052_IRQ_TBAT,
 469                .flags = IORESOURCE_IRQ,
 470        },
 471        {
 472                .name = "DCIN DET",
 473                .start = DA9052_IRQ_DCIN,
 474                .end   = DA9052_IRQ_DCIN,
 475                .flags = IORESOURCE_IRQ,
 476        },
 477        {
 478                .name = "DCIN REM",
 479                .start = DA9052_IRQ_DCINREM,
 480                .end   = DA9052_IRQ_DCINREM,
 481                .flags = IORESOURCE_IRQ,
 482        },
 483        {
 484                .name = "VBUS DET",
 485                .start = DA9052_IRQ_VBUS,
 486                .end   = DA9052_IRQ_VBUS,
 487                .flags = IORESOURCE_IRQ,
 488        },
 489        {
 490                .name = "VBUS REM",
 491                .start = DA9052_IRQ_VBUSREM,
 492                .end   = DA9052_IRQ_VBUSREM,
 493                .flags = IORESOURCE_IRQ,
 494        },
 495        {
 496                .name = "CHG END",
 497                .start = DA9052_IRQ_CHGEND,
 498                .end   = DA9052_IRQ_CHGEND,
 499                .flags = IORESOURCE_IRQ,
 500        },
 501};
 502
 503static struct resource da9052_tsi_resources[] = {
 504        {
 505                .name = "PENDWN",
 506                .start = DA9052_IRQ_PENDOWN,
 507                .end   = DA9052_IRQ_PENDOWN,
 508                .flags = IORESOURCE_IRQ,
 509        },
 510        {
 511                .name = "TSIRDY",
 512                .start = DA9052_IRQ_TSIREADY,
 513                .end   = DA9052_IRQ_TSIREADY,
 514                .flags = IORESOURCE_IRQ,
 515        },
 516};
 517
 518static struct mfd_cell __devinitdata da9052_subdev_info[] = {
 519        {
 520                .name = "da9052-regulator",
 521                .id = 1,
 522        },
 523        {
 524                .name = "da9052-regulator",
 525                .id = 2,
 526        },
 527        {
 528                .name = "da9052-regulator",
 529                .id = 3,
 530        },
 531        {
 532                .name = "da9052-regulator",
 533                .id = 4,
 534        },
 535        {
 536                .name = "da9052-regulator",
 537                .id = 5,
 538        },
 539        {
 540                .name = "da9052-regulator",
 541                .id = 6,
 542        },
 543        {
 544                .name = "da9052-regulator",
 545                .id = 7,
 546        },
 547        {
 548                .name = "da9052-regulator",
 549                .id = 8,
 550        },
 551        {
 552                .name = "da9052-regulator",
 553                .id = 9,
 554        },
 555        {
 556                .name = "da9052-regulator",
 557                .id = 10,
 558        },
 559        {
 560                .name = "da9052-regulator",
 561                .id = 11,
 562        },
 563        {
 564                .name = "da9052-regulator",
 565                .id = 12,
 566        },
 567        {
 568                .name = "da9052-regulator",
 569                .id = 13,
 570        },
 571        {
 572                .name = "da9052-regulator",
 573                .id = 14,
 574        },
 575        {
 576                .name = "da9052-onkey",
 577                .resources = &da9052_onkey_resource,
 578                .num_resources = 1,
 579        },
 580        {
 581                .name = "da9052-rtc",
 582                .resources = &da9052_rtc_resource,
 583                .num_resources = 1,
 584        },
 585        {
 586                .name = "da9052-gpio",
 587        },
 588        {
 589                .name = "da9052-hwmon",
 590        },
 591        {
 592                .name = "da9052-leds",
 593        },
 594        {
 595                .name = "da9052-wled1",
 596        },
 597        {
 598                .name = "da9052-wled2",
 599        },
 600        {
 601                .name = "da9052-wled3",
 602        },
 603        {
 604                .name = "da9052-tsi",
 605                .resources = da9052_tsi_resources,
 606                .num_resources = ARRAY_SIZE(da9052_tsi_resources),
 607        },
 608        {
 609                .name = "da9052-bat",
 610                .resources = da9052_bat_resources,
 611                .num_resources = ARRAY_SIZE(da9052_bat_resources),
 612        },
 613        {
 614                .name = "da9052-watchdog",
 615        },
 616};
 617
 618static struct regmap_irq da9052_irqs[] = {
 619        [DA9052_IRQ_DCIN] = {
 620                .reg_offset = 0,
 621                .mask = DA9052_IRQ_MASK_POS_1,
 622        },
 623        [DA9052_IRQ_VBUS] = {
 624                .reg_offset = 0,
 625                .mask = DA9052_IRQ_MASK_POS_2,
 626        },
 627        [DA9052_IRQ_DCINREM] = {
 628                .reg_offset = 0,
 629                .mask = DA9052_IRQ_MASK_POS_3,
 630        },
 631        [DA9052_IRQ_VBUSREM] = {
 632                .reg_offset = 0,
 633                .mask = DA9052_IRQ_MASK_POS_4,
 634        },
 635        [DA9052_IRQ_VDDLOW] = {
 636                .reg_offset = 0,
 637                .mask = DA9052_IRQ_MASK_POS_5,
 638        },
 639        [DA9052_IRQ_ALARM] = {
 640                .reg_offset = 0,
 641                .mask = DA9052_IRQ_MASK_POS_6,
 642        },
 643        [DA9052_IRQ_SEQRDY] = {
 644                .reg_offset = 0,
 645                .mask = DA9052_IRQ_MASK_POS_7,
 646        },
 647        [DA9052_IRQ_COMP1V2] = {
 648                .reg_offset = 0,
 649                .mask = DA9052_IRQ_MASK_POS_8,
 650        },
 651        [DA9052_IRQ_NONKEY] = {
 652                .reg_offset = 1,
 653                .mask = DA9052_IRQ_MASK_POS_1,
 654        },
 655        [DA9052_IRQ_IDFLOAT] = {
 656                .reg_offset = 1,
 657                .mask = DA9052_IRQ_MASK_POS_2,
 658        },
 659        [DA9052_IRQ_IDGND] = {
 660                .reg_offset = 1,
 661                .mask = DA9052_IRQ_MASK_POS_3,
 662        },
 663        [DA9052_IRQ_CHGEND] = {
 664                .reg_offset = 1,
 665                .mask = DA9052_IRQ_MASK_POS_4,
 666        },
 667        [DA9052_IRQ_TBAT] = {
 668                .reg_offset = 1,
 669                .mask = DA9052_IRQ_MASK_POS_5,
 670        },
 671        [DA9052_IRQ_ADC_EOM] = {
 672                .reg_offset = 1,
 673                .mask = DA9052_IRQ_MASK_POS_6,
 674        },
 675        [DA9052_IRQ_PENDOWN] = {
 676                .reg_offset = 1,
 677                .mask = DA9052_IRQ_MASK_POS_7,
 678        },
 679        [DA9052_IRQ_TSIREADY] = {
 680                .reg_offset = 1,
 681                .mask = DA9052_IRQ_MASK_POS_8,
 682        },
 683        [DA9052_IRQ_GPI0] = {
 684                .reg_offset = 2,
 685                .mask = DA9052_IRQ_MASK_POS_1,
 686        },
 687        [DA9052_IRQ_GPI1] = {
 688                .reg_offset = 2,
 689                .mask = DA9052_IRQ_MASK_POS_2,
 690        },
 691        [DA9052_IRQ_GPI2] = {
 692                .reg_offset = 2,
 693                .mask = DA9052_IRQ_MASK_POS_3,
 694        },
 695        [DA9052_IRQ_GPI3] = {
 696                .reg_offset = 2,
 697                .mask = DA9052_IRQ_MASK_POS_4,
 698        },
 699        [DA9052_IRQ_GPI4] = {
 700                .reg_offset = 2,
 701                .mask = DA9052_IRQ_MASK_POS_5,
 702        },
 703        [DA9052_IRQ_GPI5] = {
 704                .reg_offset = 2,
 705                .mask = DA9052_IRQ_MASK_POS_6,
 706        },
 707        [DA9052_IRQ_GPI6] = {
 708                .reg_offset = 2,
 709                .mask = DA9052_IRQ_MASK_POS_7,
 710        },
 711        [DA9052_IRQ_GPI7] = {
 712                .reg_offset = 2,
 713                .mask = DA9052_IRQ_MASK_POS_8,
 714        },
 715        [DA9052_IRQ_GPI8] = {
 716                .reg_offset = 3,
 717                .mask = DA9052_IRQ_MASK_POS_1,
 718        },
 719        [DA9052_IRQ_GPI9] = {
 720                .reg_offset = 3,
 721                .mask = DA9052_IRQ_MASK_POS_2,
 722        },
 723        [DA9052_IRQ_GPI10] = {
 724                .reg_offset = 3,
 725                .mask = DA9052_IRQ_MASK_POS_3,
 726        },
 727        [DA9052_IRQ_GPI11] = {
 728                .reg_offset = 3,
 729                .mask = DA9052_IRQ_MASK_POS_4,
 730        },
 731        [DA9052_IRQ_GPI12] = {
 732                .reg_offset = 3,
 733                .mask = DA9052_IRQ_MASK_POS_5,
 734        },
 735        [DA9052_IRQ_GPI13] = {
 736                .reg_offset = 3,
 737                .mask = DA9052_IRQ_MASK_POS_6,
 738        },
 739        [DA9052_IRQ_GPI14] = {
 740                .reg_offset = 3,
 741                .mask = DA9052_IRQ_MASK_POS_7,
 742        },
 743        [DA9052_IRQ_GPI15] = {
 744                .reg_offset = 3,
 745                .mask = DA9052_IRQ_MASK_POS_8,
 746        },
 747};
 748
 749static struct regmap_irq_chip da9052_regmap_irq_chip = {
 750        .name = "da9052_irq",
 751        .status_base = DA9052_EVENT_A_REG,
 752        .mask_base = DA9052_IRQ_MASK_A_REG,
 753        .ack_base = DA9052_EVENT_A_REG,
 754        .num_regs = DA9052_NUM_IRQ_REGS,
 755        .irqs = da9052_irqs,
 756        .num_irqs = ARRAY_SIZE(da9052_irqs),
 757};
 758
 759struct regmap_config da9052_regmap_config = {
 760        .reg_bits = 8,
 761        .val_bits = 8,
 762
 763        .cache_type = REGCACHE_RBTREE,
 764
 765        .max_register = DA9052_PAGE1_CON_REG,
 766        .readable_reg = da9052_reg_readable,
 767        .writeable_reg = da9052_reg_writeable,
 768        .volatile_reg = da9052_reg_volatile,
 769};
 770EXPORT_SYMBOL_GPL(da9052_regmap_config);
 771
 772int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
 773{
 774        struct da9052_pdata *pdata = da9052->dev->platform_data;
 775        int ret;
 776
 777        mutex_init(&da9052->auxadc_lock);
 778        init_completion(&da9052->done);
 779
 780        if (pdata && pdata->init != NULL)
 781                pdata->init(da9052);
 782
 783        da9052->chip_id = chip_id;
 784
 785        if (!pdata || !pdata->irq_base)
 786                da9052->irq_base = -1;
 787        else
 788                da9052->irq_base = pdata->irq_base;
 789
 790        ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
 791                                  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 792                                  da9052->irq_base, &da9052_regmap_irq_chip,
 793                                  &da9052->irq_data);
 794        if (ret < 0)
 795                goto regmap_err;
 796
 797        da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data);
 798
 799        ret = request_threaded_irq(DA9052_IRQ_ADC_EOM, NULL, da9052_auxadc_irq,
 800                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 801                                   "adc irq", da9052);
 802        if (ret != 0)
 803                dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);
 804
 805        ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
 806                              ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL);
 807        if (ret)
 808                goto err;
 809
 810        return 0;
 811
 812err:
 813        free_irq(DA9052_IRQ_ADC_EOM, da9052);
 814        mfd_remove_devices(da9052->dev);
 815regmap_err:
 816        return ret;
 817}
 818
 819void da9052_device_exit(struct da9052 *da9052)
 820{
 821        free_irq(DA9052_IRQ_ADC_EOM, da9052);
 822        regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
 823        mfd_remove_devices(da9052->dev);
 824}
 825
 826MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
 827MODULE_DESCRIPTION("DA9052 MFD Core");
 828MODULE_LICENSE("GPL");
 829
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.