aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/da9063-i2c.c
diff options
context:
space:
mode:
authorKrystian Garbaciak <krystian.garbaciak@diasemi.com>2013-07-29 13:00:43 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-08-19 21:15:52 -0400
commit8e685483b0ba17fe08cfc36fb86b3688a24b2090 (patch)
tree5d555fb3056e88923d8c058d32ed9ab2c28ae5a8 /drivers/mfd/da9063-i2c.c
parent36ec66e0333355112148549f9846adcc0909482e (diff)
mfd: da9063: Add Dialog DA9063 core driver
This is MFD module providing access to registers and interrupts of DA906x series PMIC. It is used by other functional modules, registered as MFD cells. Driver uses regmap with paging to access extended register list. Register map is divided into two pages, where the second page is used during initialisation. This module provides support to following functional cells: - Regulators - RTC - HWMON - OnKey (power key misc input device) - Vibration (force-feedback input device) - Watchdog - LEDs Signed-off-by: Krystian Garbaciak <krystian.garbaciak@diasemi.com> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Mark Brown <broonie@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/da9063-i2c.c')
-rw-r--r--drivers/mfd/da9063-i2c.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
new file mode 100644
index 000000000000..8db5c805c64f
--- /dev/null
+++ b/drivers/mfd/da9063-i2c.c
@@ -0,0 +1,182 @@
1/* da9063-i2c.c: Interrupt support for Dialog DA9063
2 *
3 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix
5 *
6 * Author: Krystian Garbaciak <krystian.garbaciak@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
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/i2c.h>
18#include <linux/regmap.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/err.h>
22
23#include <linux/mfd/core.h>
24#include <linux/mfd/da9063/core.h>
25#include <linux/mfd/da9063/pdata.h>
26#include <linux/mfd/da9063/registers.h>
27
28static const struct regmap_range da9063_readable_ranges[] = {
29 {
30 .range_min = DA9063_REG_PAGE_CON,
31 .range_max = DA9063_REG_SECOND_D,
32 }, {
33 .range_min = DA9063_REG_SEQ,
34 .range_max = DA9063_REG_ID_32_31,
35 }, {
36 .range_min = DA9063_REG_SEQ_A,
37 .range_max = DA9063_REG_AUTO3_LOW,
38 }, {
39 .range_min = DA9063_REG_T_OFFSET,
40 .range_max = DA9063_REG_GP_ID_19,
41 }, {
42 .range_min = DA9063_REG_CHIP_ID,
43 .range_max = DA9063_REG_CHIP_VARIANT,
44 },
45};
46
47static const struct regmap_range da9063_writeable_ranges[] = {
48 {
49 .range_min = DA9063_REG_PAGE_CON,
50 .range_max = DA9063_REG_PAGE_CON,
51 }, {
52 .range_min = DA9063_REG_FAULT_LOG,
53 .range_max = DA9063_REG_VSYS_MON,
54 }, {
55 .range_min = DA9063_REG_COUNT_S,
56 .range_max = DA9063_REG_ALARM_Y,
57 }, {
58 .range_min = DA9063_REG_SEQ,
59 .range_max = DA9063_REG_ID_32_31,
60 }, {
61 .range_min = DA9063_REG_SEQ_A,
62 .range_max = DA9063_REG_AUTO3_LOW,
63 }, {
64 .range_min = DA9063_REG_CONFIG_I,
65 .range_max = DA9063_REG_MON_REG_4,
66 }, {
67 .range_min = DA9063_REG_GP_ID_0,
68 .range_max = DA9063_REG_GP_ID_19,
69 },
70};
71
72static const struct regmap_range da9063_volatile_ranges[] = {
73 {
74 .range_min = DA9063_REG_STATUS_A,
75 .range_max = DA9063_REG_EVENT_D,
76 }, {
77 .range_min = DA9063_REG_CONTROL_F,
78 .range_max = DA9063_REG_CONTROL_F,
79 }, {
80 .range_min = DA9063_REG_ADC_MAN,
81 .range_max = DA9063_REG_ADC_MAN,
82 }, {
83 .range_min = DA9063_REG_ADC_RES_L,
84 .range_max = DA9063_REG_SECOND_D,
85 }, {
86 .range_min = DA9063_REG_MON_REG_5,
87 .range_max = DA9063_REG_MON_REG_6,
88 },
89};
90
91static const struct regmap_access_table da9063_readable_table = {
92 .yes_ranges = da9063_readable_ranges,
93 .n_yes_ranges = ARRAY_SIZE(da9063_readable_ranges),
94};
95
96static const struct regmap_access_table da9063_writeable_table = {
97 .yes_ranges = da9063_writeable_ranges,
98 .n_yes_ranges = ARRAY_SIZE(da9063_writeable_ranges),
99};
100
101static const struct regmap_access_table da9063_volatile_table = {
102 .yes_ranges = da9063_volatile_ranges,
103 .n_yes_ranges = ARRAY_SIZE(da9063_volatile_ranges),
104};
105
106static const struct regmap_range_cfg da9063_range_cfg[] = {
107 {
108 .range_min = DA9063_REG_PAGE_CON,
109 .range_max = DA9063_REG_CHIP_VARIANT,
110 .selector_reg = DA9063_REG_PAGE_CON,
111 .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT,
112 .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT,
113 .window_start = 0,
114 .window_len = 256,
115 }
116};
117
118static struct regmap_config da9063_regmap_config = {
119 .reg_bits = 8,
120 .val_bits = 8,
121 .ranges = da9063_range_cfg,
122 .num_ranges = ARRAY_SIZE(da9063_range_cfg),
123 .max_register = DA9063_REG_CHIP_VARIANT,
124
125 .cache_type = REGCACHE_RBTREE,
126
127 .rd_table = &da9063_readable_table,
128 .wr_table = &da9063_writeable_table,
129 .volatile_table = &da9063_volatile_table,
130};
131
132static int da9063_i2c_probe(struct i2c_client *i2c,
133 const struct i2c_device_id *id)
134{
135 struct da9063 *da9063;
136 int ret;
137
138 da9063 = devm_kzalloc(&i2c->dev, sizeof(struct da9063), GFP_KERNEL);
139 if (da9063 == NULL)
140 return -ENOMEM;
141
142 i2c_set_clientdata(i2c, da9063);
143 da9063->dev = &i2c->dev;
144 da9063->chip_irq = i2c->irq;
145
146 da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
147 if (IS_ERR(da9063->regmap)) {
148 ret = PTR_ERR(da9063->regmap);
149 dev_err(da9063->dev, "Failed to allocate register map: %d\n",
150 ret);
151 return ret;
152 }
153
154 return da9063_device_init(da9063, i2c->irq);
155}
156
157static int da9063_i2c_remove(struct i2c_client *i2c)
158{
159 struct da9063 *da9063 = i2c_get_clientdata(i2c);
160
161 da9063_device_exit(da9063);
162
163 return 0;
164}
165
166static const struct i2c_device_id da9063_i2c_id[] = {
167 {"da9063", PMIC_DA9063},
168 {},
169};
170MODULE_DEVICE_TABLE(i2c, da9063_i2c_id);
171
172static struct i2c_driver da9063_i2c_driver = {
173 .driver = {
174 .name = "da9063",
175 .owner = THIS_MODULE,
176 },
177 .probe = da9063_i2c_probe,
178 .remove = da9063_i2c_remove,
179 .id_table = da9063_i2c_id,
180};
181
182module_i2c_driver(da9063_i2c_driver);