tps6507x-regulator.c 15.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * tps6507x-regulator.c
 *
 * Regulator driver for TPS65073 PMIC
 *
 * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
 * whether express or implied; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
25
#include <linux/regulator/tps6507x.h>
26
#include <linux/delay.h>
27
#include <linux/slab.h>
28
#include <linux/mfd/tps6507x.h>
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

/* DCDC's */
#define TPS6507X_DCDC_1				0
#define TPS6507X_DCDC_2				1
#define TPS6507X_DCDC_3				2
/* LDOs */
#define TPS6507X_LDO_1				3
#define TPS6507X_LDO_2				4

#define TPS6507X_MAX_REG_ID			TPS6507X_LDO_2

/* Number of step-down converters available */
#define TPS6507X_NUM_DCDC			3
/* Number of LDO voltage regulators  available */
#define TPS6507X_NUM_LDO			2
/* Number of total regulators available */
#define TPS6507X_NUM_REGULATOR		(TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO)

/* Supported voltage values for regulators (in milliVolts) */
static const u16 VDCDCx_VSEL_table[] = {
	725, 750, 775, 800,
	825, 850, 875, 900,
	925, 950, 975, 1000,
	1025, 1050, 1075, 1100,
	1125, 1150, 1175, 1200,
	1225, 1250, 1275, 1300,
	1325, 1350, 1375, 1400,
	1425, 1450, 1475, 1500,
	1550, 1600, 1650, 1700,
	1750, 1800, 1850, 1900,
	1950, 2000, 2050, 2100,
	2150, 2200, 2250, 2300,
	2350, 2400, 2450, 2500,
	2550, 2600, 2650, 2700,
	2750, 2800, 2850, 2900,
	3000, 3100, 3200, 3300,
};

static const u16 LDO1_VSEL_table[] = {
	1000, 1100, 1200, 1250,
	1300, 1350, 1400, 1500,
	1600, 1800, 2500, 2750,
	2800, 3000, 3100, 3300,
};

static const u16 LDO2_VSEL_table[] = {
	725, 750, 775, 800,
	825, 850, 875, 900,
	925, 950, 975, 1000,
	1025, 1050, 1075, 1100,
	1125, 1150, 1175, 1200,
	1225, 1250, 1275, 1300,
	1325, 1350, 1375, 1400,
	1425, 1450, 1475, 1500,
	1550, 1600, 1650, 1700,
	1750, 1800, 1850, 1900,
	1950, 2000, 2050, 2100,
	2150, 2200, 2250, 2300,
	2350, 2400, 2450, 2500,
	2550, 2600, 2650, 2700,
	2750, 2800, 2850, 2900,
	3000, 3100, 3200, 3300,
};

static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDCx_VSEL_table),
				ARRAY_SIZE(VDCDCx_VSEL_table),
				ARRAY_SIZE(VDCDCx_VSEL_table),
				ARRAY_SIZE(LDO1_VSEL_table),
				ARRAY_SIZE(LDO2_VSEL_table)};

struct tps_info {
	const char *name;
	unsigned min_uV;
	unsigned max_uV;
	u8 table_len;
	const u16 *table;
105 106 107

	/* Does DCDC high or the low register defines output voltage? */
	bool defdcdc_default;
108 109
};

110
static struct tps_info tps6507x_pmic_regs[] = {
T
Todd Fischer 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
	{
		.name = "VDCDC1",
		.min_uV = 725000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
		.table = VDCDCx_VSEL_table,
	},
	{
		.name = "VDCDC2",
		.min_uV = 725000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
		.table = VDCDCx_VSEL_table,
	},
	{
		.name = "VDCDC3",
		.min_uV = 725000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
		.table = VDCDCx_VSEL_table,
	},
	{
		.name = "LDO1",
		.min_uV = 1000000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(LDO1_VSEL_table),
		.table = LDO1_VSEL_table,
	},
	{
		.name = "LDO2",
		.min_uV = 725000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(LDO2_VSEL_table),
		.table = LDO2_VSEL_table,
	},
};

148
struct tps6507x_pmic {
149
	struct regulator_desc desc[TPS6507X_NUM_REGULATOR];
T
Todd Fischer 已提交
150
	struct tps6507x_dev *mfd;
151
	struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR];
152
	struct tps_info *info[TPS6507X_NUM_REGULATOR];
153 154
	struct mutex io_lock;
};
155
static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg)
156
{
T
Todd Fischer 已提交
157 158 159 160 161 162 163 164 165
	u8 val;
	int err;

	err = tps->mfd->read_dev(tps->mfd, reg, 1, &val);

	if (err)
		return err;

	return val;
166 167
}

168
static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
169
{
T
Todd Fischer 已提交
170
	return tps->mfd->write_dev(tps->mfd, reg, 1, &val);
171 172
}

173
static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
174 175 176 177 178
{
	int err, data;

	mutex_lock(&tps->io_lock);

179
	data = tps6507x_pmic_read(tps, reg);
180
	if (data < 0) {
T
Todd Fischer 已提交
181
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
182 183 184 185 186
		err = data;
		goto out;
	}

	data |= mask;
187
	err = tps6507x_pmic_write(tps, reg, data);
188
	if (err)
T
Todd Fischer 已提交
189
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
190 191 192 193 194 195

out:
	mutex_unlock(&tps->io_lock);
	return err;
}

196
static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
197 198 199 200 201
{
	int err, data;

	mutex_lock(&tps->io_lock);

202
	data = tps6507x_pmic_read(tps, reg);
203
	if (data < 0) {
T
Todd Fischer 已提交
204
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
205 206 207 208 209
		err = data;
		goto out;
	}

	data &= ~mask;
210
	err = tps6507x_pmic_write(tps, reg, data);
211
	if (err)
T
Todd Fischer 已提交
212
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
213 214 215 216 217 218

out:
	mutex_unlock(&tps->io_lock);
	return err;
}

219
static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg)
220 221 222 223 224
{
	int data;

	mutex_lock(&tps->io_lock);

225
	data = tps6507x_pmic_read(tps, reg);
226
	if (data < 0)
T
Todd Fischer 已提交
227
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
228 229 230 231 232

	mutex_unlock(&tps->io_lock);
	return data;
}

233
static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
234 235 236 237 238
{
	int err;

	mutex_lock(&tps->io_lock);

239
	err = tps6507x_pmic_write(tps, reg, val);
240
	if (err < 0)
T
Todd Fischer 已提交
241
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
242 243 244 245 246

	mutex_unlock(&tps->io_lock);
	return err;
}

247
static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev)
248
{
249
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
250 251 252 253 254 255 256
	int data, dcdc = rdev_get_id(dev);
	u8 shift;

	if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - dcdc;
257
	data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
258 259 260 261 262 263 264

	if (data < 0)
		return data;
	else
		return (data & 1<<shift) ? 1 : 0;
}

265
static int tps6507x_pmic_ldo_is_enabled(struct regulator_dev *dev)
266
{
267
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
268 269 270 271 272 273 274
	int data, ldo = rdev_get_id(dev);
	u8 shift;

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - ldo;
275
	data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
276 277 278 279 280 281 282

	if (data < 0)
		return data;
	else
		return (data & 1<<shift) ? 1 : 0;
}

283
static int tps6507x_pmic_dcdc_enable(struct regulator_dev *dev)
284
{
285
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
286 287 288 289 290 291 292
	int dcdc = rdev_get_id(dev);
	u8 shift;

	if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - dcdc;
293
	return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
294 295
}

296
static int tps6507x_pmic_dcdc_disable(struct regulator_dev *dev)
297
{
298
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
299 300 301 302 303 304 305
	int dcdc = rdev_get_id(dev);
	u8 shift;

	if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - dcdc;
306 307
	return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
					1 << shift);
308 309
}

310
static int tps6507x_pmic_ldo_enable(struct regulator_dev *dev)
311
{
312
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
313 314 315 316 317 318 319
	int ldo = rdev_get_id(dev);
	u8 shift;

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - ldo;
320
	return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
321 322
}

323
static int tps6507x_pmic_ldo_disable(struct regulator_dev *dev)
324
{
325
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
326 327 328 329 330 331 332
	int ldo = rdev_get_id(dev);
	u8 shift;

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;

	shift = TPS6507X_MAX_REG_ID - ldo;
333 334
	return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
					1 << shift);
335 336
}

337
static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev)
338
{
339
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
340 341 342 343 344 345 346 347
	int data, dcdc = rdev_get_id(dev);
	u8 reg;

	switch (dcdc) {
	case TPS6507X_DCDC_1:
		reg = TPS6507X_REG_DEFDCDC1;
		break;
	case TPS6507X_DCDC_2:
348 349 350 351
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC2_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC2_LOW;
352 353
		break;
	case TPS6507X_DCDC_3:
354 355 356 357
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC3_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC3_LOW;
358 359 360 361 362
		break;
	default:
		return -EINVAL;
	}

363
	data = tps6507x_pmic_reg_read(tps, reg);
364 365 366 367 368 369 370
	if (data < 0)
		return data;

	data &= TPS6507X_DEFDCDCX_DCDC_MASK;
	return tps->info[dcdc]->table[data] * 1000;
}

371
static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev,
372 373
					  int min_uV, int max_uV,
					  unsigned *selector)
374
{
375
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
376 377 378 379 380 381 382 383
	int data, vsel, dcdc = rdev_get_id(dev);
	u8 reg;

	switch (dcdc) {
	case TPS6507X_DCDC_1:
		reg = TPS6507X_REG_DEFDCDC1;
		break;
	case TPS6507X_DCDC_2:
384 385 386 387
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC2_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC2_LOW;
388 389
		break;
	case TPS6507X_DCDC_3:
390 391 392 393
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC3_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC3_LOW;
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
		break;
	default:
		return -EINVAL;
	}

	if (min_uV < tps->info[dcdc]->min_uV
		|| min_uV > tps->info[dcdc]->max_uV)
		return -EINVAL;
	if (max_uV < tps->info[dcdc]->min_uV
		|| max_uV > tps->info[dcdc]->max_uV)
		return -EINVAL;

	for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) {
		int mV = tps->info[dcdc]->table[vsel];
		int uV = mV * 1000;

		/* Break at the first in-range value */
		if (min_uV <= uV && uV <= max_uV)
			break;
	}

	/* write to the register in case we found a match */
	if (vsel == tps->info[dcdc]->table_len)
		return -EINVAL;

419 420
	*selector = vsel;

421
	data = tps6507x_pmic_reg_read(tps, reg);
422 423 424 425 426 427
	if (data < 0)
		return data;

	data &= ~TPS6507X_DEFDCDCX_DCDC_MASK;
	data |= vsel;

428
	return tps6507x_pmic_reg_write(tps, reg, data);
429 430
}

431
static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev)
432
{
433
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
434 435 436 437 438 439 440 441 442 443 444 445 446
	int data, ldo = rdev_get_id(dev);
	u8 reg, mask;

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;
	else {
		reg = (ldo == TPS6507X_LDO_1 ?
			TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2);
		mask = (ldo == TPS6507X_LDO_1 ?
			TPS6507X_REG_LDO_CTRL1_LDO1_MASK :
				TPS6507X_REG_DEFLDO2_LDO2_MASK);
	}

447
	data = tps6507x_pmic_reg_read(tps, reg);
448 449 450 451 452 453 454
	if (data < 0)
		return data;

	data &= mask;
	return tps->info[ldo]->table[data] * 1000;
}

455
static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev,
456 457
					 int min_uV, int max_uV,
					 unsigned *selector)
458
{
459
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
	int data, vsel, ldo = rdev_get_id(dev);
	u8 reg, mask;

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;
	else {
		reg = (ldo == TPS6507X_LDO_1 ?
			TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2);
		mask = (ldo == TPS6507X_LDO_1 ?
			TPS6507X_REG_LDO_CTRL1_LDO1_MASK :
				TPS6507X_REG_DEFLDO2_LDO2_MASK);
	}

	if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
		return -EINVAL;
	if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
		return -EINVAL;

	for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
		int mV = tps->info[ldo]->table[vsel];
		int uV = mV * 1000;

		/* Break at the first in-range value */
		if (min_uV <= uV && uV <= max_uV)
			break;
	}

	if (vsel == tps->info[ldo]->table_len)
		return -EINVAL;

490 491
	*selector = vsel;

492
	data = tps6507x_pmic_reg_read(tps, reg);
493 494 495 496 497 498
	if (data < 0)
		return data;

	data &= ~mask;
	data |= vsel;

499
	return tps6507x_pmic_reg_write(tps, reg, data);
500 501
}

502
static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev,
503 504
					unsigned selector)
{
505
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
506 507 508 509 510 511 512 513 514 515 516
	int dcdc = rdev_get_id(dev);

	if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
		return -EINVAL;

	if (selector >= tps->info[dcdc]->table_len)
		return -EINVAL;
	else
		return tps->info[dcdc]->table[selector] * 1000;
}

517
static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev,
518 519
					unsigned selector)
{
520
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
521 522 523 524 525 526 527 528 529 530 531 532
	int ldo = rdev_get_id(dev);

	if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
		return -EINVAL;

	if (selector >= tps->info[ldo]->table_len)
		return -EINVAL;
	else
		return tps->info[ldo]->table[selector] * 1000;
}

/* Operations permitted on VDCDCx */
533 534 535 536 537 538 539
static struct regulator_ops tps6507x_pmic_dcdc_ops = {
	.is_enabled = tps6507x_pmic_dcdc_is_enabled,
	.enable = tps6507x_pmic_dcdc_enable,
	.disable = tps6507x_pmic_dcdc_disable,
	.get_voltage = tps6507x_pmic_dcdc_get_voltage,
	.set_voltage = tps6507x_pmic_dcdc_set_voltage,
	.list_voltage = tps6507x_pmic_dcdc_list_voltage,
540 541 542
};

/* Operations permitted on LDOx */
543 544 545 546 547 548 549
static struct regulator_ops tps6507x_pmic_ldo_ops = {
	.is_enabled = tps6507x_pmic_ldo_is_enabled,
	.enable = tps6507x_pmic_ldo_enable,
	.disable = tps6507x_pmic_ldo_disable,
	.get_voltage = tps6507x_pmic_ldo_get_voltage,
	.set_voltage = tps6507x_pmic_ldo_set_voltage,
	.list_voltage = tps6507x_pmic_ldo_list_voltage,
550 551
};

T
Todd Fischer 已提交
552 553
static __devinit
int tps6507x_pmic_probe(struct platform_device *pdev)
554
{
T
Todd Fischer 已提交
555
	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
556
	static int desc_id;
557
	struct tps_info *info = &tps6507x_pmic_regs[0];
558 559
	struct regulator_init_data *init_data;
	struct regulator_dev *rdev;
560
	struct tps6507x_pmic *tps;
561
	struct tps6507x_board *tps_board;
562
	int i;
563
	int error;
564

565 566 567 568 569
	/**
	 * tps_board points to pmic related constants
	 * coming from the board-evm file.
	 */

T
Todd Fischer 已提交
570
	tps_board = dev_get_platdata(tps6507x_dev->dev);
571 572 573
	if (!tps_board)
		return -EINVAL;

574 575 576 577
	/**
	 * init_data points to array of regulator_init structures
	 * coming from the board-evm file.
	 */
578
	init_data = tps_board->tps6507x_pmic_init_data;
579
	if (!init_data)
580
		return -EINVAL;
581 582 583 584 585 586 587 588

	tps = kzalloc(sizeof(*tps), GFP_KERNEL);
	if (!tps)
		return -ENOMEM;

	mutex_init(&tps->io_lock);

	/* common for all regulators */
T
Todd Fischer 已提交
589
	tps->mfd = tps6507x_dev;
590 591 592 593

	for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) {
		/* Register the regulators */
		tps->info[i] = info;
594 595 596 597 598 599
		if (init_data->driver_data) {
			struct tps6507x_reg_platform_data *data =
							init_data->driver_data;
			tps->info[i]->defdcdc_default = data->defdcdc_default;
		}

600 601 602 603
		tps->desc[i].name = info->name;
		tps->desc[i].id = desc_id++;
		tps->desc[i].n_voltages = num_voltages[i];
		tps->desc[i].ops = (i > TPS6507X_DCDC_3 ?
604
		&tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
605 606 607 608
		tps->desc[i].type = REGULATOR_VOLTAGE;
		tps->desc[i].owner = THIS_MODULE;

		rdev = regulator_register(&tps->desc[i],
T
Todd Fischer 已提交
609
					tps6507x_dev->dev, init_data, tps);
610
		if (IS_ERR(rdev)) {
T
Todd Fischer 已提交
611 612 613
			dev_err(tps6507x_dev->dev,
				"failed to register %s regulator\n",
				pdev->name);
614 615
			error = PTR_ERR(rdev);
			goto fail;
616 617 618 619 620 621
		}

		/* Save regulator for cleanup */
		tps->rdev[i] = rdev;
	}

T
Todd Fischer 已提交
622
	tps6507x_dev->pmic = tps;
623
	platform_set_drvdata(pdev, tps6507x_dev);
624 625

	return 0;
626 627 628 629 630 631 632

fail:
	while (--i >= 0)
		regulator_unregister(tps->rdev[i]);

	kfree(tps);
	return error;
633 634
}

T
Todd Fischer 已提交
635
static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
636
{
T
Todd Fischer 已提交
637 638
	struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
	struct tps6507x_pmic *tps = tps6507x_dev->pmic;
639 640 641 642 643 644 645 646 647 648
	int i;

	for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
		regulator_unregister(tps->rdev[i]);

	kfree(tps);

	return 0;
}

T
Todd Fischer 已提交
649
static struct platform_driver tps6507x_pmic_driver = {
650
	.driver = {
T
Todd Fischer 已提交
651
		.name = "tps6507x-pmic",
652 653
		.owner = THIS_MODULE,
	},
654 655
	.probe = tps6507x_pmic_probe,
	.remove = __devexit_p(tps6507x_pmic_remove),
656 657 658
};

/**
659
 * tps6507x_pmic_init
660 661 662
 *
 * Module init function
 */
663
static int __init tps6507x_pmic_init(void)
664
{
T
Todd Fischer 已提交
665
	return platform_driver_register(&tps6507x_pmic_driver);
666
}
667
subsys_initcall(tps6507x_pmic_init);
668 669

/**
670
 * tps6507x_pmic_cleanup
671 672 673
 *
 * Module exit function
 */
674
static void __exit tps6507x_pmic_cleanup(void)
675
{
T
Todd Fischer 已提交
676
	platform_driver_unregister(&tps6507x_pmic_driver);
677
}
678
module_exit(tps6507x_pmic_cleanup);
679 680 681

MODULE_AUTHOR("Texas Instruments");
MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
682
MODULE_LICENSE("GPL v2");
T
Todd Fischer 已提交
683
MODULE_ALIAS("platform:tps6507x-pmic");