1/*
2 * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
3 *
4 * Supported Part Numbers:
5 * FAN53555UC00X/01X/03X/04X/05X
6 *
7 * Copyright (c) 2012 Marvell Technology Ltd.
8 * Yunfan Zhang <yfzhang@marvell.com>
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15#include <linux/module.h>
16#include <linux/param.h>
17#include <linux/err.h>
18#include <linux/platform_device.h>
19#include <linux/regulator/driver.h>
20#include <linux/regulator/machine.h>
21#include <linux/regulator/of_regulator.h>
22#include <linux/of_device.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/regmap.h>
26#include <linux/regulator/fan53555.h>
27
28/* Voltage setting */
29#define FAN53555_VSEL0		0x00
30#define FAN53555_VSEL1		0x01
31/* Control register */
32#define FAN53555_CONTROL	0x02
33/* IC Type */
34#define FAN53555_ID1		0x03
35/* IC mask version */
36#define FAN53555_ID2		0x04
37/* Monitor register */
38#define FAN53555_MONITOR	0x05
39
40/* VSEL bit definitions */
41#define VSEL_BUCK_EN	(1 << 7)
42#define VSEL_MODE		(1 << 6)
43#define VSEL_NSEL_MASK	0x3F
44/* Chip ID and Verison */
45#define DIE_ID		0x0F	/* ID1 */
46#define DIE_REV		0x0F	/* ID2 */
47/* Control bit definitions */
48#define CTL_OUTPUT_DISCHG	(1 << 7)
49#define CTL_SLEW_MASK		(0x7 << 4)
50#define CTL_SLEW_SHIFT		4
51#define CTL_RESET			(1 << 2)
52
53#define FAN53555_NVOLTAGES	64	/* Numbers of voltages */
54
55enum fan53555_vendor {
56	FAN53555_VENDOR_FAIRCHILD = 0,
57	FAN53555_VENDOR_SILERGY,
58};
59
60/* IC Type */
61enum {
62	FAN53555_CHIP_ID_00 = 0,
63	FAN53555_CHIP_ID_01,
64	FAN53555_CHIP_ID_02,
65	FAN53555_CHIP_ID_03,
66	FAN53555_CHIP_ID_04,
67	FAN53555_CHIP_ID_05,
68};
69
70enum {
71	SILERGY_SYR82X = 8,
72};
73
74struct fan53555_device_info {
75	enum fan53555_vendor vendor;
76	struct regmap *regmap;
77	struct device *dev;
78	struct regulator_desc desc;
79	struct regulator_dev *rdev;
80	struct regulator_init_data *regulator;
81	/* IC Type and Rev */
82	int chip_id;
83	int chip_rev;
84	/* Voltage setting register */
85	unsigned int vol_reg;
86	unsigned int sleep_reg;
87	/* Voltage range and step(linear) */
88	unsigned int vsel_min;
89	unsigned int vsel_step;
90	/* Voltage slew rate limiting */
91	unsigned int slew_rate;
92	/* Sleep voltage cache */
93	unsigned int sleep_vol_cache;
94};
95
96static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
97{
98	struct fan53555_device_info *di = rdev_get_drvdata(rdev);
99	int ret;
100
101	if (di->sleep_vol_cache == uV)
102		return 0;
103	ret = regulator_map_voltage_linear(rdev, uV, uV);
104	if (ret < 0)
105		return ret;
106	ret = regmap_update_bits(di->regmap, di->sleep_reg,
107					VSEL_NSEL_MASK, ret);
108	if (ret < 0)
109		return ret;
110	/* Cache the sleep voltage setting.
111	 * Might not be the real voltage which is rounded */
112	di->sleep_vol_cache = uV;
113
114	return 0;
115}
116
117static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
118{
119	struct fan53555_device_info *di = rdev_get_drvdata(rdev);
120
121	switch (mode) {
122	case REGULATOR_MODE_FAST:
123		regmap_update_bits(di->regmap, di->vol_reg,
124				VSEL_MODE, VSEL_MODE);
125		break;
126	case REGULATOR_MODE_NORMAL:
127		regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0);
128		break;
129	default:
130		return -EINVAL;
131	}
132	return 0;
133}
134
135static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
136{
137	struct fan53555_device_info *di = rdev_get_drvdata(rdev);
138	unsigned int val;
139	int ret = 0;
140
141	ret = regmap_read(di->regmap, di->vol_reg, &val);
142	if (ret < 0)
143		return ret;
144	if (val & VSEL_MODE)
145		return REGULATOR_MODE_FAST;
146	else
147		return REGULATOR_MODE_NORMAL;
148}
149
150static int slew_rates[] = {
151	64000,
152	32000,
153	16000,
154	 8000,
155	 4000,
156	 2000,
157	 1000,
158	  500,
159};
160
161static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
162{
163	struct fan53555_device_info *di = rdev_get_drvdata(rdev);
164	int regval = -1, i;
165
166	for (i = 0; i < ARRAY_SIZE(slew_rates); i++) {
167		if (ramp <= slew_rates[i])
168			regval = i;
169		else
170			break;
171	}
172
173	if (regval < 0) {
174		dev_err(di->dev, "unsupported ramp value %d\n", ramp);
175		return -EINVAL;
176	}
177
178	return regmap_update_bits(di->regmap, FAN53555_CONTROL,
179				  CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
180}
181
182static struct regulator_ops fan53555_regulator_ops = {
183	.set_voltage_sel = regulator_set_voltage_sel_regmap,
184	.get_voltage_sel = regulator_get_voltage_sel_regmap,
185	.map_voltage = regulator_map_voltage_linear,
186	.list_voltage = regulator_list_voltage_linear,
187	.set_suspend_voltage = fan53555_set_suspend_voltage,
188	.enable = regulator_enable_regmap,
189	.disable = regulator_disable_regmap,
190	.is_enabled = regulator_is_enabled_regmap,
191	.set_mode = fan53555_set_mode,
192	.get_mode = fan53555_get_mode,
193	.set_ramp_delay = fan53555_set_ramp,
194};
195
196static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
197{
198	/* Init voltage range and step */
199	switch (di->chip_id) {
200	case FAN53555_CHIP_ID_00:
201	case FAN53555_CHIP_ID_01:
202	case FAN53555_CHIP_ID_03:
203	case FAN53555_CHIP_ID_05:
204		di->vsel_min = 600000;
205		di->vsel_step = 10000;
206		break;
207	case FAN53555_CHIP_ID_04:
208		di->vsel_min = 603000;
209		di->vsel_step = 12826;
210		break;
211	default:
212		dev_err(di->dev,
213			"Chip ID %d not supported!\n", di->chip_id);
214		return -EINVAL;
215	}
216
217	return 0;
218}
219
220static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
221{
222	/* Init voltage range and step */
223	switch (di->chip_id) {
224	case SILERGY_SYR82X:
225		di->vsel_min = 712500;
226		di->vsel_step = 12500;
227		break;
228	default:
229		dev_err(di->dev,
230			"Chip ID %d not supported!\n", di->chip_id);
231		return -EINVAL;
232	}
233
234	return 0;
235}
236
237/* For 00,01,03,05 options:
238 * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
239 * For 04 option:
240 * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
241 * */
242static int fan53555_device_setup(struct fan53555_device_info *di,
243				struct fan53555_platform_data *pdata)
244{
245	int ret = 0;
246
247	/* Setup voltage control register */
248	switch (pdata->sleep_vsel_id) {
249	case FAN53555_VSEL_ID_0:
250		di->sleep_reg = FAN53555_VSEL0;
251		di->vol_reg = FAN53555_VSEL1;
252		break;
253	case FAN53555_VSEL_ID_1:
254		di->sleep_reg = FAN53555_VSEL1;
255		di->vol_reg = FAN53555_VSEL0;
256		break;
257	default:
258		dev_err(di->dev, "Invalid VSEL ID!\n");
259		return -EINVAL;
260	}
261
262	switch (di->vendor) {
263	case FAN53555_VENDOR_FAIRCHILD:
264		ret = fan53555_voltages_setup_fairchild(di);
265		break;
266	case FAN53555_VENDOR_SILERGY:
267		ret = fan53555_voltages_setup_silergy(di);
268		break;
269	default:
270		dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
271		return -EINVAL;
272	}
273
274	return ret;
275}
276
277static int fan53555_regulator_register(struct fan53555_device_info *di,
278			struct regulator_config *config)
279{
280	struct regulator_desc *rdesc = &di->desc;
281
282	rdesc->name = "fan53555-reg";
283	rdesc->supply_name = "vin";
284	rdesc->ops = &fan53555_regulator_ops;
285	rdesc->type = REGULATOR_VOLTAGE;
286	rdesc->n_voltages = FAN53555_NVOLTAGES;
287	rdesc->enable_reg = di->vol_reg;
288	rdesc->enable_mask = VSEL_BUCK_EN;
289	rdesc->min_uV = di->vsel_min;
290	rdesc->uV_step = di->vsel_step;
291	rdesc->vsel_reg = di->vol_reg;
292	rdesc->vsel_mask = VSEL_NSEL_MASK;
293	rdesc->owner = THIS_MODULE;
294
295	di->rdev = devm_regulator_register(di->dev, &di->desc, config);
296	return PTR_ERR_OR_ZERO(di->rdev);
297}
298
299static struct regmap_config fan53555_regmap_config = {
300	.reg_bits = 8,
301	.val_bits = 8,
302};
303
304static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
305							struct device_node *np)
306{
307	struct fan53555_platform_data *pdata;
308	int ret;
309	u32 tmp;
310
311	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
312	if (!pdata)
313		return NULL;
314
315	pdata->regulator = of_get_regulator_init_data(dev, np);
316
317	ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
318				   &tmp);
319	if (!ret)
320		pdata->sleep_vsel_id = tmp;
321
322	return pdata;
323}
324
325static const struct of_device_id fan53555_dt_ids[] = {
326	{
327		.compatible = "fcs,fan53555",
328		.data = (void *)FAN53555_VENDOR_FAIRCHILD
329	}, {
330		.compatible = "silergy,syr827",
331		.data = (void *)FAN53555_VENDOR_SILERGY,
332	}, {
333		.compatible = "silergy,syr828",
334		.data = (void *)FAN53555_VENDOR_SILERGY,
335	},
336	{ }
337};
338MODULE_DEVICE_TABLE(of, fan53555_dt_ids);
339
340static int fan53555_regulator_probe(struct i2c_client *client,
341				const struct i2c_device_id *id)
342{
343	struct device_node *np = client->dev.of_node;
344	struct fan53555_device_info *di;
345	struct fan53555_platform_data *pdata;
346	struct regulator_config config = { };
347	unsigned int val;
348	int ret;
349
350	pdata = dev_get_platdata(&client->dev);
351	if (!pdata)
352		pdata = fan53555_parse_dt(&client->dev, np);
353
354	if (!pdata || !pdata->regulator) {
355		dev_err(&client->dev, "Platform data not found!\n");
356		return -ENODEV;
357	}
358
359	di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
360					GFP_KERNEL);
361	if (!di)
362		return -ENOMEM;
363
364	di->regulator = pdata->regulator;
365	if (client->dev.of_node) {
366		const struct of_device_id *match;
367
368		match = of_match_device(of_match_ptr(fan53555_dt_ids),
369					&client->dev);
370		if (!match)
371			return -ENODEV;
372
373		di->vendor = (unsigned long) match->data;
374	} else {
375		/* if no ramp constraint set, get the pdata ramp_delay */
376		if (!di->regulator->constraints.ramp_delay) {
377			int slew_idx = (pdata->slew_rate & 0x7)
378						? pdata->slew_rate : 0;
379
380			di->regulator->constraints.ramp_delay
381						= slew_rates[slew_idx];
382		}
383
384		di->vendor = id->driver_data;
385	}
386
387	di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
388	if (IS_ERR(di->regmap)) {
389		dev_err(&client->dev, "Failed to allocate regmap!\n");
390		return PTR_ERR(di->regmap);
391	}
392	di->dev = &client->dev;
393	i2c_set_clientdata(client, di);
394	/* Get chip ID */
395	ret = regmap_read(di->regmap, FAN53555_ID1, &val);
396	if (ret < 0) {
397		dev_err(&client->dev, "Failed to get chip ID!\n");
398		return ret;
399	}
400	di->chip_id = val & DIE_ID;
401	/* Get chip revision */
402	ret = regmap_read(di->regmap, FAN53555_ID2, &val);
403	if (ret < 0) {
404		dev_err(&client->dev, "Failed to get chip Rev!\n");
405		return ret;
406	}
407	di->chip_rev = val & DIE_REV;
408	dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
409				di->chip_id, di->chip_rev);
410	/* Device init */
411	ret = fan53555_device_setup(di, pdata);
412	if (ret < 0) {
413		dev_err(&client->dev, "Failed to setup device!\n");
414		return ret;
415	}
416	/* Register regulator */
417	config.dev = di->dev;
418	config.init_data = di->regulator;
419	config.regmap = di->regmap;
420	config.driver_data = di;
421	config.of_node = np;
422
423	ret = fan53555_regulator_register(di, &config);
424	if (ret < 0)
425		dev_err(&client->dev, "Failed to register regulator!\n");
426	return ret;
427
428}
429
430static const struct i2c_device_id fan53555_id[] = {
431	{
432		.name = "fan53555",
433		.driver_data = FAN53555_VENDOR_FAIRCHILD
434	}, {
435		.name = "syr82x",
436		.driver_data = FAN53555_VENDOR_SILERGY
437	},
438	{ },
439};
440
441static struct i2c_driver fan53555_regulator_driver = {
442	.driver = {
443		.name = "fan53555-regulator",
444		.of_match_table = of_match_ptr(fan53555_dt_ids),
445	},
446	.probe = fan53555_regulator_probe,
447	.id_table = fan53555_id,
448};
449
450module_i2c_driver(fan53555_regulator_driver);
451
452MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
453MODULE_DESCRIPTION("FAN53555 regulator driver");
454MODULE_LICENSE("GPL v2");
455