root/drivers/mfd/da9055-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. da9055_register_readable
  2. da9055_register_writeable
  3. da9055_register_volatile
  4. da9055_device_init
  5. da9055_device_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Device access for Dialog DA9055 PMICs.
   4  *
   5  * Copyright(c) 2012 Dialog Semiconductor Ltd.
   6  *
   7  * Author: David Dajun Chen <dchen@diasemi.com>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/device.h>
  12 #include <linux/input.h>
  13 #include <linux/irq.h>
  14 #include <linux/mutex.h>
  15 
  16 #include <linux/mfd/core.h>
  17 #include <linux/mfd/da9055/core.h>
  18 #include <linux/mfd/da9055/pdata.h>
  19 #include <linux/mfd/da9055/reg.h>
  20 
  21 #define DA9055_IRQ_NONKEY_MASK          0x01
  22 #define DA9055_IRQ_ALM_MASK             0x02
  23 #define DA9055_IRQ_TICK_MASK            0x04
  24 #define DA9055_IRQ_ADC_MASK             0x08
  25 #define DA9055_IRQ_BUCK_ILIM_MASK       0x08
  26 
  27 static bool da9055_register_readable(struct device *dev, unsigned int reg)
  28 {
  29         switch (reg) {
  30         case DA9055_REG_STATUS_A:
  31         case DA9055_REG_STATUS_B:
  32         case DA9055_REG_EVENT_A:
  33         case DA9055_REG_EVENT_B:
  34         case DA9055_REG_EVENT_C:
  35         case DA9055_REG_IRQ_MASK_A:
  36         case DA9055_REG_IRQ_MASK_B:
  37         case DA9055_REG_IRQ_MASK_C:
  38 
  39         case DA9055_REG_CONTROL_A:
  40         case DA9055_REG_CONTROL_B:
  41         case DA9055_REG_CONTROL_C:
  42         case DA9055_REG_CONTROL_D:
  43         case DA9055_REG_CONTROL_E:
  44 
  45         case DA9055_REG_ADC_MAN:
  46         case DA9055_REG_ADC_CONT:
  47         case DA9055_REG_VSYS_MON:
  48         case DA9055_REG_ADC_RES_L:
  49         case DA9055_REG_ADC_RES_H:
  50         case DA9055_REG_VSYS_RES:
  51         case DA9055_REG_ADCIN1_RES:
  52         case DA9055_REG_ADCIN2_RES:
  53         case DA9055_REG_ADCIN3_RES:
  54 
  55         case DA9055_REG_COUNT_S:
  56         case DA9055_REG_COUNT_MI:
  57         case DA9055_REG_COUNT_H:
  58         case DA9055_REG_COUNT_D:
  59         case DA9055_REG_COUNT_MO:
  60         case DA9055_REG_COUNT_Y:
  61         case DA9055_REG_ALARM_H:
  62         case DA9055_REG_ALARM_D:
  63         case DA9055_REG_ALARM_MI:
  64         case DA9055_REG_ALARM_MO:
  65         case DA9055_REG_ALARM_Y:
  66 
  67         case DA9055_REG_GPIO0_1:
  68         case DA9055_REG_GPIO2:
  69         case DA9055_REG_GPIO_MODE0_2:
  70 
  71         case DA9055_REG_BCORE_CONT:
  72         case DA9055_REG_BMEM_CONT:
  73         case DA9055_REG_LDO1_CONT:
  74         case DA9055_REG_LDO2_CONT:
  75         case DA9055_REG_LDO3_CONT:
  76         case DA9055_REG_LDO4_CONT:
  77         case DA9055_REG_LDO5_CONT:
  78         case DA9055_REG_LDO6_CONT:
  79         case DA9055_REG_BUCK_LIM:
  80         case DA9055_REG_BCORE_MODE:
  81         case DA9055_REG_VBCORE_A:
  82         case DA9055_REG_VBMEM_A:
  83         case DA9055_REG_VLDO1_A:
  84         case DA9055_REG_VLDO2_A:
  85         case DA9055_REG_VLDO3_A:
  86         case DA9055_REG_VLDO4_A:
  87         case DA9055_REG_VLDO5_A:
  88         case DA9055_REG_VLDO6_A:
  89         case DA9055_REG_VBCORE_B:
  90         case DA9055_REG_VBMEM_B:
  91         case DA9055_REG_VLDO1_B:
  92         case DA9055_REG_VLDO2_B:
  93         case DA9055_REG_VLDO3_B:
  94         case DA9055_REG_VLDO4_B:
  95         case DA9055_REG_VLDO5_B:
  96         case DA9055_REG_VLDO6_B:
  97                 return true;
  98         default:
  99                 return false;
 100         }
 101 }
 102 
 103 static bool da9055_register_writeable(struct device *dev, unsigned int reg)
 104 {
 105         switch (reg) {
 106         case DA9055_REG_STATUS_A:
 107         case DA9055_REG_STATUS_B:
 108         case DA9055_REG_EVENT_A:
 109         case DA9055_REG_EVENT_B:
 110         case DA9055_REG_EVENT_C:
 111         case DA9055_REG_IRQ_MASK_A:
 112         case DA9055_REG_IRQ_MASK_B:
 113         case DA9055_REG_IRQ_MASK_C:
 114 
 115         case DA9055_REG_CONTROL_A:
 116         case DA9055_REG_CONTROL_B:
 117         case DA9055_REG_CONTROL_C:
 118         case DA9055_REG_CONTROL_D:
 119         case DA9055_REG_CONTROL_E:
 120 
 121         case DA9055_REG_ADC_MAN:
 122         case DA9055_REG_ADC_CONT:
 123         case DA9055_REG_VSYS_MON:
 124         case DA9055_REG_ADC_RES_L:
 125         case DA9055_REG_ADC_RES_H:
 126         case DA9055_REG_VSYS_RES:
 127         case DA9055_REG_ADCIN1_RES:
 128         case DA9055_REG_ADCIN2_RES:
 129         case DA9055_REG_ADCIN3_RES:
 130 
 131         case DA9055_REG_COUNT_S:
 132         case DA9055_REG_COUNT_MI:
 133         case DA9055_REG_COUNT_H:
 134         case DA9055_REG_COUNT_D:
 135         case DA9055_REG_COUNT_MO:
 136         case DA9055_REG_COUNT_Y:
 137         case DA9055_REG_ALARM_H:
 138         case DA9055_REG_ALARM_D:
 139         case DA9055_REG_ALARM_MI:
 140         case DA9055_REG_ALARM_MO:
 141         case DA9055_REG_ALARM_Y:
 142 
 143         case DA9055_REG_GPIO0_1:
 144         case DA9055_REG_GPIO2:
 145         case DA9055_REG_GPIO_MODE0_2:
 146 
 147         case DA9055_REG_BCORE_CONT:
 148         case DA9055_REG_BMEM_CONT:
 149         case DA9055_REG_LDO1_CONT:
 150         case DA9055_REG_LDO2_CONT:
 151         case DA9055_REG_LDO3_CONT:
 152         case DA9055_REG_LDO4_CONT:
 153         case DA9055_REG_LDO5_CONT:
 154         case DA9055_REG_LDO6_CONT:
 155         case DA9055_REG_BUCK_LIM:
 156         case DA9055_REG_BCORE_MODE:
 157         case DA9055_REG_VBCORE_A:
 158         case DA9055_REG_VBMEM_A:
 159         case DA9055_REG_VLDO1_A:
 160         case DA9055_REG_VLDO2_A:
 161         case DA9055_REG_VLDO3_A:
 162         case DA9055_REG_VLDO4_A:
 163         case DA9055_REG_VLDO5_A:
 164         case DA9055_REG_VLDO6_A:
 165         case DA9055_REG_VBCORE_B:
 166         case DA9055_REG_VBMEM_B:
 167         case DA9055_REG_VLDO1_B:
 168         case DA9055_REG_VLDO2_B:
 169         case DA9055_REG_VLDO3_B:
 170         case DA9055_REG_VLDO4_B:
 171         case DA9055_REG_VLDO5_B:
 172         case DA9055_REG_VLDO6_B:
 173                 return true;
 174         default:
 175                 return false;
 176         }
 177 }
 178 
 179 static bool da9055_register_volatile(struct device *dev, unsigned int reg)
 180 {
 181         switch (reg) {
 182         case DA9055_REG_STATUS_A:
 183         case DA9055_REG_STATUS_B:
 184         case DA9055_REG_EVENT_A:
 185         case DA9055_REG_EVENT_B:
 186         case DA9055_REG_EVENT_C:
 187 
 188         case DA9055_REG_CONTROL_A:
 189         case DA9055_REG_CONTROL_E:
 190 
 191         case DA9055_REG_ADC_MAN:
 192         case DA9055_REG_ADC_RES_L:
 193         case DA9055_REG_ADC_RES_H:
 194         case DA9055_REG_VSYS_RES:
 195         case DA9055_REG_ADCIN1_RES:
 196         case DA9055_REG_ADCIN2_RES:
 197         case DA9055_REG_ADCIN3_RES:
 198 
 199         case DA9055_REG_COUNT_S:
 200         case DA9055_REG_COUNT_MI:
 201         case DA9055_REG_COUNT_H:
 202         case DA9055_REG_COUNT_D:
 203         case DA9055_REG_COUNT_MO:
 204         case DA9055_REG_COUNT_Y:
 205         case DA9055_REG_ALARM_MI:
 206 
 207         case DA9055_REG_BCORE_CONT:
 208         case DA9055_REG_BMEM_CONT:
 209         case DA9055_REG_LDO1_CONT:
 210         case DA9055_REG_LDO2_CONT:
 211         case DA9055_REG_LDO3_CONT:
 212         case DA9055_REG_LDO4_CONT:
 213         case DA9055_REG_LDO5_CONT:
 214         case DA9055_REG_LDO6_CONT:
 215                 return true;
 216         default:
 217                 return false;
 218         }
 219 }
 220 
 221 static const struct regmap_irq da9055_irqs[] = {
 222         [DA9055_IRQ_NONKEY] = {
 223                 .reg_offset = 0,
 224                 .mask = DA9055_IRQ_NONKEY_MASK,
 225         },
 226         [DA9055_IRQ_ALARM] = {
 227                 .reg_offset = 0,
 228                 .mask = DA9055_IRQ_ALM_MASK,
 229         },
 230         [DA9055_IRQ_TICK] = {
 231                 .reg_offset = 0,
 232                 .mask = DA9055_IRQ_TICK_MASK,
 233         },
 234         [DA9055_IRQ_HWMON] = {
 235                 .reg_offset = 0,
 236                 .mask = DA9055_IRQ_ADC_MASK,
 237         },
 238         [DA9055_IRQ_REGULATOR] = {
 239                 .reg_offset = 1,
 240                 .mask = DA9055_IRQ_BUCK_ILIM_MASK,
 241         },
 242 };
 243 
 244 const struct regmap_config da9055_regmap_config = {
 245         .reg_bits = 8,
 246         .val_bits = 8,
 247 
 248         .cache_type = REGCACHE_RBTREE,
 249 
 250         .max_register = DA9055_MAX_REGISTER_CNT,
 251         .readable_reg = da9055_register_readable,
 252         .writeable_reg = da9055_register_writeable,
 253         .volatile_reg = da9055_register_volatile,
 254 };
 255 EXPORT_SYMBOL_GPL(da9055_regmap_config);
 256 
 257 static struct resource da9055_onkey_resource = {
 258         .name = "ONKEY",
 259         .start = DA9055_IRQ_NONKEY,
 260         .end   = DA9055_IRQ_NONKEY,
 261         .flags = IORESOURCE_IRQ,
 262 };
 263 
 264 static struct resource da9055_rtc_resource[] = {
 265         {
 266                 .name = "ALM",
 267                 .start = DA9055_IRQ_ALARM,
 268                 .end   = DA9055_IRQ_ALARM,
 269                 .flags = IORESOURCE_IRQ,
 270         },
 271         {
 272                 .name = "TICK",
 273                 .start = DA9055_IRQ_TICK,
 274                 .end   = DA9055_IRQ_TICK,
 275                 .flags = IORESOURCE_IRQ,
 276         },
 277 };
 278 
 279 static struct resource da9055_hwmon_resource = {
 280         .name = "HWMON",
 281         .start = DA9055_IRQ_HWMON,
 282         .end   = DA9055_IRQ_HWMON,
 283         .flags = IORESOURCE_IRQ,
 284 };
 285 
 286 static struct resource da9055_ld05_6_resource = {
 287         .name = "REGULATOR",
 288         .start = DA9055_IRQ_REGULATOR,
 289         .end   = DA9055_IRQ_REGULATOR,
 290         .flags = IORESOURCE_IRQ,
 291 };
 292 
 293 static const struct mfd_cell da9055_devs[] = {
 294         {
 295                 .of_compatible = "dlg,da9055-gpio",
 296                 .name = "da9055-gpio",
 297         },
 298         {
 299                 .of_compatible = "dlg,da9055-regulator",
 300                 .name = "da9055-regulator",
 301                 .id = 1,
 302         },
 303         {
 304                 .of_compatible = "dlg,da9055-regulator",
 305                 .name = "da9055-regulator",
 306                 .id = 2,
 307         },
 308         {
 309                 .of_compatible = "dlg,da9055-regulator",
 310                 .name = "da9055-regulator",
 311                 .id = 3,
 312         },
 313         {
 314                 .of_compatible = "dlg,da9055-regulator",
 315                 .name = "da9055-regulator",
 316                 .id = 4,
 317         },
 318         {
 319                 .of_compatible = "dlg,da9055-regulator",
 320                 .name = "da9055-regulator",
 321                 .id = 5,
 322         },
 323         {
 324                 .of_compatible = "dlg,da9055-regulator",
 325                 .name = "da9055-regulator",
 326                 .id = 6,
 327         },
 328         {
 329                 .of_compatible = "dlg,da9055-regulator",
 330                 .name = "da9055-regulator",
 331                 .id = 7,
 332                 .resources = &da9055_ld05_6_resource,
 333                 .num_resources = 1,
 334         },
 335         {
 336                 .of_compatible = "dlg,da9055-regulator",
 337                 .name = "da9055-regulator",
 338                 .resources = &da9055_ld05_6_resource,
 339                 .num_resources = 1,
 340                 .id = 8,
 341         },
 342         {
 343                 .of_compatible = "dlg,da9055-onkey",
 344                 .name = "da9055-onkey",
 345                 .resources = &da9055_onkey_resource,
 346                 .num_resources = 1,
 347         },
 348         {
 349                 .of_compatible = "dlg,da9055-rtc",
 350                 .name = "da9055-rtc",
 351                 .resources = da9055_rtc_resource,
 352                 .num_resources = ARRAY_SIZE(da9055_rtc_resource),
 353         },
 354         {
 355                 .of_compatible = "dlg,da9055-hwmon",
 356                 .name = "da9055-hwmon",
 357                 .resources = &da9055_hwmon_resource,
 358                 .num_resources = 1,
 359         },
 360         {
 361                 .of_compatible = "dlg,da9055-watchdog",
 362                 .name = "da9055-watchdog",
 363         },
 364 };
 365 
 366 static const struct regmap_irq_chip da9055_regmap_irq_chip = {
 367         .name = "da9055_irq",
 368         .status_base = DA9055_REG_EVENT_A,
 369         .mask_base = DA9055_REG_IRQ_MASK_A,
 370         .ack_base = DA9055_REG_EVENT_A,
 371         .num_regs = 3,
 372         .irqs = da9055_irqs,
 373         .num_irqs = ARRAY_SIZE(da9055_irqs),
 374 };
 375 
 376 int da9055_device_init(struct da9055 *da9055)
 377 {
 378         struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
 379         int ret;
 380         uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
 381 
 382         if (pdata && pdata->init != NULL)
 383                 pdata->init(da9055);
 384 
 385         if (!pdata || !pdata->irq_base)
 386                 da9055->irq_base = -1;
 387         else
 388                 da9055->irq_base = pdata->irq_base;
 389 
 390         ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
 391         if (ret < 0)
 392                 return ret;
 393 
 394         ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
 395                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 396                                   da9055->irq_base, &da9055_regmap_irq_chip,
 397                                   &da9055->irq_data);
 398         if (ret < 0)
 399                 return ret;
 400 
 401         da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
 402 
 403         ret = mfd_add_devices(da9055->dev, -1,
 404                               da9055_devs, ARRAY_SIZE(da9055_devs),
 405                               NULL, da9055->irq_base, NULL);
 406         if (ret)
 407                 goto err;
 408 
 409         return 0;
 410 
 411 err:
 412         mfd_remove_devices(da9055->dev);
 413         return ret;
 414 }
 415 
 416 void da9055_device_exit(struct da9055 *da9055)
 417 {
 418         regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
 419         mfd_remove_devices(da9055->dev);
 420 }
 421 
 422 MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
 423 MODULE_LICENSE("GPL");
 424 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");

/* [<][>][^][v][top][bottom][index][help] */