brintos

brintos / linux-shallow public Read only

0
0
Text · 9.2 KiB · 1f727ef Raw
402 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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		0x0122#define DA9055_IRQ_ALM_MASK		0x0223#define DA9055_IRQ_TICK_MASK		0x0424#define DA9055_IRQ_ADC_MASK		0x0825#define DA9055_IRQ_BUCK_ILIM_MASK	0x0826 27static 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 103static 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 179static 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 221static 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 244const struct regmap_config da9055_regmap_config = {245	.reg_bits = 8,246	.val_bits = 8,247 248	.cache_type = REGCACHE_MAPLE,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};255EXPORT_SYMBOL_GPL(da9055_regmap_config);256 257static const struct resource da9055_onkey_resource =258	DEFINE_RES_IRQ_NAMED(DA9055_IRQ_NONKEY, "ONKEY");259 260static const struct resource da9055_rtc_resource[] = {261	DEFINE_RES_IRQ_NAMED(DA9055_IRQ_ALARM, "ALM"),262	DEFINE_RES_IRQ_NAMED(DA9055_IRQ_TICK, "TICK"),263};264 265static const struct resource da9055_hwmon_resource =266	DEFINE_RES_IRQ_NAMED(DA9055_IRQ_HWMON, "HWMON");267 268static const struct resource da9055_ld05_6_resource =269	DEFINE_RES_IRQ_NAMED(DA9055_IRQ_REGULATOR, "REGULATOR");270 271static const struct mfd_cell da9055_devs[] = {272	{273		.of_compatible = "dlg,da9055-gpio",274		.name = "da9055-gpio",275	},276	{277		.of_compatible = "dlg,da9055-regulator",278		.name = "da9055-regulator",279		.id = 1,280	},281	{282		.of_compatible = "dlg,da9055-regulator",283		.name = "da9055-regulator",284		.id = 2,285	},286	{287		.of_compatible = "dlg,da9055-regulator",288		.name = "da9055-regulator",289		.id = 3,290	},291	{292		.of_compatible = "dlg,da9055-regulator",293		.name = "da9055-regulator",294		.id = 4,295	},296	{297		.of_compatible = "dlg,da9055-regulator",298		.name = "da9055-regulator",299		.id = 5,300	},301	{302		.of_compatible = "dlg,da9055-regulator",303		.name = "da9055-regulator",304		.id = 6,305	},306	{307		.of_compatible = "dlg,da9055-regulator",308		.name = "da9055-regulator",309		.id = 7,310		.resources = &da9055_ld05_6_resource,311		.num_resources = 1,312	},313	{314		.of_compatible = "dlg,da9055-regulator",315		.name = "da9055-regulator",316		.resources = &da9055_ld05_6_resource,317		.num_resources = 1,318		.id = 8,319	},320	{321		.of_compatible = "dlg,da9055-onkey",322		.name = "da9055-onkey",323		.resources = &da9055_onkey_resource,324		.num_resources = 1,325	},326	{327		.of_compatible = "dlg,da9055-rtc",328		.name = "da9055-rtc",329		.resources = da9055_rtc_resource,330		.num_resources = ARRAY_SIZE(da9055_rtc_resource),331	},332	{333		.of_compatible = "dlg,da9055-hwmon",334		.name = "da9055-hwmon",335		.resources = &da9055_hwmon_resource,336		.num_resources = 1,337	},338	{339		.of_compatible = "dlg,da9055-watchdog",340		.name = "da9055-watchdog",341	},342};343 344static const struct regmap_irq_chip da9055_regmap_irq_chip = {345	.name = "da9055_irq",346	.status_base = DA9055_REG_EVENT_A,347	.mask_base = DA9055_REG_IRQ_MASK_A,348	.ack_base = DA9055_REG_EVENT_A,349	.num_regs = 3,350	.irqs = da9055_irqs,351	.num_irqs = ARRAY_SIZE(da9055_irqs),352};353 354int da9055_device_init(struct da9055 *da9055)355{356	struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);357	int ret;358	uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};359 360	if (pdata && pdata->init != NULL)361		pdata->init(da9055);362 363	if (!pdata || !pdata->irq_base)364		da9055->irq_base = -1;365	else366		da9055->irq_base = pdata->irq_base;367 368	ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);369	if (ret < 0)370		return ret;371 372	ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,373				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,374				  da9055->irq_base, &da9055_regmap_irq_chip,375				  &da9055->irq_data);376	if (ret < 0)377		return ret;378 379	da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);380 381	ret = mfd_add_devices(da9055->dev, -1,382			      da9055_devs, ARRAY_SIZE(da9055_devs),383			      NULL, da9055->irq_base, NULL);384	if (ret)385		goto err;386 387	return 0;388 389err:390	mfd_remove_devices(da9055->dev);391	return ret;392}393 394void da9055_device_exit(struct da9055 *da9055)395{396	regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);397	mfd_remove_devices(da9055->dev);398}399 400MODULE_DESCRIPTION("Core support for the DA9055 PMIC");401MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");402