0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/device.h>
0012 #include <linux/input.h>
0013 #include <linux/irq.h>
0014 #include <linux/mutex.h>
0015
0016 #include <linux/mfd/core.h>
0017 #include <linux/mfd/da9055/core.h>
0018 #include <linux/mfd/da9055/pdata.h>
0019 #include <linux/mfd/da9055/reg.h>
0020
0021 #define DA9055_IRQ_NONKEY_MASK 0x01
0022 #define DA9055_IRQ_ALM_MASK 0x02
0023 #define DA9055_IRQ_TICK_MASK 0x04
0024 #define DA9055_IRQ_ADC_MASK 0x08
0025 #define DA9055_IRQ_BUCK_ILIM_MASK 0x08
0026
0027 static bool da9055_register_readable(struct device *dev, unsigned int reg)
0028 {
0029 switch (reg) {
0030 case DA9055_REG_STATUS_A:
0031 case DA9055_REG_STATUS_B:
0032 case DA9055_REG_EVENT_A:
0033 case DA9055_REG_EVENT_B:
0034 case DA9055_REG_EVENT_C:
0035 case DA9055_REG_IRQ_MASK_A:
0036 case DA9055_REG_IRQ_MASK_B:
0037 case DA9055_REG_IRQ_MASK_C:
0038
0039 case DA9055_REG_CONTROL_A:
0040 case DA9055_REG_CONTROL_B:
0041 case DA9055_REG_CONTROL_C:
0042 case DA9055_REG_CONTROL_D:
0043 case DA9055_REG_CONTROL_E:
0044
0045 case DA9055_REG_ADC_MAN:
0046 case DA9055_REG_ADC_CONT:
0047 case DA9055_REG_VSYS_MON:
0048 case DA9055_REG_ADC_RES_L:
0049 case DA9055_REG_ADC_RES_H:
0050 case DA9055_REG_VSYS_RES:
0051 case DA9055_REG_ADCIN1_RES:
0052 case DA9055_REG_ADCIN2_RES:
0053 case DA9055_REG_ADCIN3_RES:
0054
0055 case DA9055_REG_COUNT_S:
0056 case DA9055_REG_COUNT_MI:
0057 case DA9055_REG_COUNT_H:
0058 case DA9055_REG_COUNT_D:
0059 case DA9055_REG_COUNT_MO:
0060 case DA9055_REG_COUNT_Y:
0061 case DA9055_REG_ALARM_H:
0062 case DA9055_REG_ALARM_D:
0063 case DA9055_REG_ALARM_MI:
0064 case DA9055_REG_ALARM_MO:
0065 case DA9055_REG_ALARM_Y:
0066
0067 case DA9055_REG_GPIO0_1:
0068 case DA9055_REG_GPIO2:
0069 case DA9055_REG_GPIO_MODE0_2:
0070
0071 case DA9055_REG_BCORE_CONT:
0072 case DA9055_REG_BMEM_CONT:
0073 case DA9055_REG_LDO1_CONT:
0074 case DA9055_REG_LDO2_CONT:
0075 case DA9055_REG_LDO3_CONT:
0076 case DA9055_REG_LDO4_CONT:
0077 case DA9055_REG_LDO5_CONT:
0078 case DA9055_REG_LDO6_CONT:
0079 case DA9055_REG_BUCK_LIM:
0080 case DA9055_REG_BCORE_MODE:
0081 case DA9055_REG_VBCORE_A:
0082 case DA9055_REG_VBMEM_A:
0083 case DA9055_REG_VLDO1_A:
0084 case DA9055_REG_VLDO2_A:
0085 case DA9055_REG_VLDO3_A:
0086 case DA9055_REG_VLDO4_A:
0087 case DA9055_REG_VLDO5_A:
0088 case DA9055_REG_VLDO6_A:
0089 case DA9055_REG_VBCORE_B:
0090 case DA9055_REG_VBMEM_B:
0091 case DA9055_REG_VLDO1_B:
0092 case DA9055_REG_VLDO2_B:
0093 case DA9055_REG_VLDO3_B:
0094 case DA9055_REG_VLDO4_B:
0095 case DA9055_REG_VLDO5_B:
0096 case DA9055_REG_VLDO6_B:
0097 return true;
0098 default:
0099 return false;
0100 }
0101 }
0102
0103 static bool da9055_register_writeable(struct device *dev, unsigned int reg)
0104 {
0105 switch (reg) {
0106 case DA9055_REG_STATUS_A:
0107 case DA9055_REG_STATUS_B:
0108 case DA9055_REG_EVENT_A:
0109 case DA9055_REG_EVENT_B:
0110 case DA9055_REG_EVENT_C:
0111 case DA9055_REG_IRQ_MASK_A:
0112 case DA9055_REG_IRQ_MASK_B:
0113 case DA9055_REG_IRQ_MASK_C:
0114
0115 case DA9055_REG_CONTROL_A:
0116 case DA9055_REG_CONTROL_B:
0117 case DA9055_REG_CONTROL_C:
0118 case DA9055_REG_CONTROL_D:
0119 case DA9055_REG_CONTROL_E:
0120
0121 case DA9055_REG_ADC_MAN:
0122 case DA9055_REG_ADC_CONT:
0123 case DA9055_REG_VSYS_MON:
0124 case DA9055_REG_ADC_RES_L:
0125 case DA9055_REG_ADC_RES_H:
0126 case DA9055_REG_VSYS_RES:
0127 case DA9055_REG_ADCIN1_RES:
0128 case DA9055_REG_ADCIN2_RES:
0129 case DA9055_REG_ADCIN3_RES:
0130
0131 case DA9055_REG_COUNT_S:
0132 case DA9055_REG_COUNT_MI:
0133 case DA9055_REG_COUNT_H:
0134 case DA9055_REG_COUNT_D:
0135 case DA9055_REG_COUNT_MO:
0136 case DA9055_REG_COUNT_Y:
0137 case DA9055_REG_ALARM_H:
0138 case DA9055_REG_ALARM_D:
0139 case DA9055_REG_ALARM_MI:
0140 case DA9055_REG_ALARM_MO:
0141 case DA9055_REG_ALARM_Y:
0142
0143 case DA9055_REG_GPIO0_1:
0144 case DA9055_REG_GPIO2:
0145 case DA9055_REG_GPIO_MODE0_2:
0146
0147 case DA9055_REG_BCORE_CONT:
0148 case DA9055_REG_BMEM_CONT:
0149 case DA9055_REG_LDO1_CONT:
0150 case DA9055_REG_LDO2_CONT:
0151 case DA9055_REG_LDO3_CONT:
0152 case DA9055_REG_LDO4_CONT:
0153 case DA9055_REG_LDO5_CONT:
0154 case DA9055_REG_LDO6_CONT:
0155 case DA9055_REG_BUCK_LIM:
0156 case DA9055_REG_BCORE_MODE:
0157 case DA9055_REG_VBCORE_A:
0158 case DA9055_REG_VBMEM_A:
0159 case DA9055_REG_VLDO1_A:
0160 case DA9055_REG_VLDO2_A:
0161 case DA9055_REG_VLDO3_A:
0162 case DA9055_REG_VLDO4_A:
0163 case DA9055_REG_VLDO5_A:
0164 case DA9055_REG_VLDO6_A:
0165 case DA9055_REG_VBCORE_B:
0166 case DA9055_REG_VBMEM_B:
0167 case DA9055_REG_VLDO1_B:
0168 case DA9055_REG_VLDO2_B:
0169 case DA9055_REG_VLDO3_B:
0170 case DA9055_REG_VLDO4_B:
0171 case DA9055_REG_VLDO5_B:
0172 case DA9055_REG_VLDO6_B:
0173 return true;
0174 default:
0175 return false;
0176 }
0177 }
0178
0179 static bool da9055_register_volatile(struct device *dev, unsigned int reg)
0180 {
0181 switch (reg) {
0182 case DA9055_REG_STATUS_A:
0183 case DA9055_REG_STATUS_B:
0184 case DA9055_REG_EVENT_A:
0185 case DA9055_REG_EVENT_B:
0186 case DA9055_REG_EVENT_C:
0187
0188 case DA9055_REG_CONTROL_A:
0189 case DA9055_REG_CONTROL_E:
0190
0191 case DA9055_REG_ADC_MAN:
0192 case DA9055_REG_ADC_RES_L:
0193 case DA9055_REG_ADC_RES_H:
0194 case DA9055_REG_VSYS_RES:
0195 case DA9055_REG_ADCIN1_RES:
0196 case DA9055_REG_ADCIN2_RES:
0197 case DA9055_REG_ADCIN3_RES:
0198
0199 case DA9055_REG_COUNT_S:
0200 case DA9055_REG_COUNT_MI:
0201 case DA9055_REG_COUNT_H:
0202 case DA9055_REG_COUNT_D:
0203 case DA9055_REG_COUNT_MO:
0204 case DA9055_REG_COUNT_Y:
0205 case DA9055_REG_ALARM_MI:
0206
0207 case DA9055_REG_BCORE_CONT:
0208 case DA9055_REG_BMEM_CONT:
0209 case DA9055_REG_LDO1_CONT:
0210 case DA9055_REG_LDO2_CONT:
0211 case DA9055_REG_LDO3_CONT:
0212 case DA9055_REG_LDO4_CONT:
0213 case DA9055_REG_LDO5_CONT:
0214 case DA9055_REG_LDO6_CONT:
0215 return true;
0216 default:
0217 return false;
0218 }
0219 }
0220
0221 static const struct regmap_irq da9055_irqs[] = {
0222 [DA9055_IRQ_NONKEY] = {
0223 .reg_offset = 0,
0224 .mask = DA9055_IRQ_NONKEY_MASK,
0225 },
0226 [DA9055_IRQ_ALARM] = {
0227 .reg_offset = 0,
0228 .mask = DA9055_IRQ_ALM_MASK,
0229 },
0230 [DA9055_IRQ_TICK] = {
0231 .reg_offset = 0,
0232 .mask = DA9055_IRQ_TICK_MASK,
0233 },
0234 [DA9055_IRQ_HWMON] = {
0235 .reg_offset = 0,
0236 .mask = DA9055_IRQ_ADC_MASK,
0237 },
0238 [DA9055_IRQ_REGULATOR] = {
0239 .reg_offset = 1,
0240 .mask = DA9055_IRQ_BUCK_ILIM_MASK,
0241 },
0242 };
0243
0244 const struct regmap_config da9055_regmap_config = {
0245 .reg_bits = 8,
0246 .val_bits = 8,
0247
0248 .cache_type = REGCACHE_RBTREE,
0249
0250 .max_register = DA9055_MAX_REGISTER_CNT,
0251 .readable_reg = da9055_register_readable,
0252 .writeable_reg = da9055_register_writeable,
0253 .volatile_reg = da9055_register_volatile,
0254 };
0255 EXPORT_SYMBOL_GPL(da9055_regmap_config);
0256
0257 static const struct resource da9055_onkey_resource =
0258 DEFINE_RES_IRQ_NAMED(DA9055_IRQ_NONKEY, "ONKEY");
0259
0260 static const struct resource da9055_rtc_resource[] = {
0261 DEFINE_RES_IRQ_NAMED(DA9055_IRQ_ALARM, "ALM"),
0262 DEFINE_RES_IRQ_NAMED(DA9055_IRQ_TICK, "TICK"),
0263 };
0264
0265 static const struct resource da9055_hwmon_resource =
0266 DEFINE_RES_IRQ_NAMED(DA9055_IRQ_HWMON, "HWMON");
0267
0268 static const struct resource da9055_ld05_6_resource =
0269 DEFINE_RES_IRQ_NAMED(DA9055_IRQ_REGULATOR, "REGULATOR");
0270
0271 static const struct mfd_cell da9055_devs[] = {
0272 {
0273 .of_compatible = "dlg,da9055-gpio",
0274 .name = "da9055-gpio",
0275 },
0276 {
0277 .of_compatible = "dlg,da9055-regulator",
0278 .name = "da9055-regulator",
0279 .id = 1,
0280 },
0281 {
0282 .of_compatible = "dlg,da9055-regulator",
0283 .name = "da9055-regulator",
0284 .id = 2,
0285 },
0286 {
0287 .of_compatible = "dlg,da9055-regulator",
0288 .name = "da9055-regulator",
0289 .id = 3,
0290 },
0291 {
0292 .of_compatible = "dlg,da9055-regulator",
0293 .name = "da9055-regulator",
0294 .id = 4,
0295 },
0296 {
0297 .of_compatible = "dlg,da9055-regulator",
0298 .name = "da9055-regulator",
0299 .id = 5,
0300 },
0301 {
0302 .of_compatible = "dlg,da9055-regulator",
0303 .name = "da9055-regulator",
0304 .id = 6,
0305 },
0306 {
0307 .of_compatible = "dlg,da9055-regulator",
0308 .name = "da9055-regulator",
0309 .id = 7,
0310 .resources = &da9055_ld05_6_resource,
0311 .num_resources = 1,
0312 },
0313 {
0314 .of_compatible = "dlg,da9055-regulator",
0315 .name = "da9055-regulator",
0316 .resources = &da9055_ld05_6_resource,
0317 .num_resources = 1,
0318 .id = 8,
0319 },
0320 {
0321 .of_compatible = "dlg,da9055-onkey",
0322 .name = "da9055-onkey",
0323 .resources = &da9055_onkey_resource,
0324 .num_resources = 1,
0325 },
0326 {
0327 .of_compatible = "dlg,da9055-rtc",
0328 .name = "da9055-rtc",
0329 .resources = da9055_rtc_resource,
0330 .num_resources = ARRAY_SIZE(da9055_rtc_resource),
0331 },
0332 {
0333 .of_compatible = "dlg,da9055-hwmon",
0334 .name = "da9055-hwmon",
0335 .resources = &da9055_hwmon_resource,
0336 .num_resources = 1,
0337 },
0338 {
0339 .of_compatible = "dlg,da9055-watchdog",
0340 .name = "da9055-watchdog",
0341 },
0342 };
0343
0344 static const struct regmap_irq_chip da9055_regmap_irq_chip = {
0345 .name = "da9055_irq",
0346 .status_base = DA9055_REG_EVENT_A,
0347 .mask_base = DA9055_REG_IRQ_MASK_A,
0348 .ack_base = DA9055_REG_EVENT_A,
0349 .num_regs = 3,
0350 .irqs = da9055_irqs,
0351 .num_irqs = ARRAY_SIZE(da9055_irqs),
0352 };
0353
0354 int da9055_device_init(struct da9055 *da9055)
0355 {
0356 struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
0357 int ret;
0358 uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
0359
0360 if (pdata && pdata->init != NULL)
0361 pdata->init(da9055);
0362
0363 if (!pdata || !pdata->irq_base)
0364 da9055->irq_base = -1;
0365 else
0366 da9055->irq_base = pdata->irq_base;
0367
0368 ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
0369 if (ret < 0)
0370 return ret;
0371
0372 ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
0373 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0374 da9055->irq_base, &da9055_regmap_irq_chip,
0375 &da9055->irq_data);
0376 if (ret < 0)
0377 return ret;
0378
0379 da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
0380
0381 ret = mfd_add_devices(da9055->dev, -1,
0382 da9055_devs, ARRAY_SIZE(da9055_devs),
0383 NULL, da9055->irq_base, NULL);
0384 if (ret)
0385 goto err;
0386
0387 return 0;
0388
0389 err:
0390 mfd_remove_devices(da9055->dev);
0391 return ret;
0392 }
0393
0394 void da9055_device_exit(struct da9055 *da9055)
0395 {
0396 regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
0397 mfd_remove_devices(da9055->dev);
0398 }
0399
0400 MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
0401 MODULE_LICENSE("GPL");
0402 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");