tps6507x-regulator.c 15.6 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

/* 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,
};

struct tps_info {
	const char *name;
	unsigned min_uV;
	unsigned max_uV;
	u8 table_len;
	const u16 *table;
99 100 101

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

104
static struct tps_info tps6507x_pmic_regs[] = {
T
Todd Fischer 已提交
105 106 107 108 109 110 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
	{
		.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,
	},
};

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

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

	if (err)
		return err;

	return val;
160 161
}

162
static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
163
{
T
Todd Fischer 已提交
164
	return tps->mfd->write_dev(tps->mfd, reg, 1, &val);
165 166
}

167
static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
168 169 170 171 172
{
	int err, data;

	mutex_lock(&tps->io_lock);

173
	data = tps6507x_pmic_read(tps, reg);
174
	if (data < 0) {
T
Todd Fischer 已提交
175
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
176 177 178 179 180
		err = data;
		goto out;
	}

	data |= mask;
181
	err = tps6507x_pmic_write(tps, reg, data);
182
	if (err)
T
Todd Fischer 已提交
183
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
184 185 186 187 188 189

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

190
static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
191 192 193 194 195
{
	int err, data;

	mutex_lock(&tps->io_lock);

196
	data = tps6507x_pmic_read(tps, reg);
197
	if (data < 0) {
T
Todd Fischer 已提交
198
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
199 200 201 202 203
		err = data;
		goto out;
	}

	data &= ~mask;
204
	err = tps6507x_pmic_write(tps, reg, data);
205
	if (err)
T
Todd Fischer 已提交
206
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
207 208 209 210 211 212

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

213
static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg)
214 215 216 217 218
{
	int data;

	mutex_lock(&tps->io_lock);

219
	data = tps6507x_pmic_read(tps, reg);
220
	if (data < 0)
T
Todd Fischer 已提交
221
		dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
222 223 224 225 226

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

227
static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
228 229 230 231 232
{
	int err;

	mutex_lock(&tps->io_lock);

233
	err = tps6507x_pmic_write(tps, reg, val);
234
	if (err < 0)
T
Todd Fischer 已提交
235
		dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
236 237 238 239 240

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

241
static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev)
242
{
243
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
244 245 246 247 248 249 250
	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;
251
	data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
252 253 254 255 256 257 258

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

259
static int tps6507x_pmic_ldo_is_enabled(struct regulator_dev *dev)
260
{
261
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
262 263 264 265 266 267 268
	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;
269
	data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
270 271 272 273 274 275 276

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

277
static int tps6507x_pmic_dcdc_enable(struct regulator_dev *dev)
278
{
279
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
280 281 282 283 284 285 286
	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;
287
	return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
288 289
}

290
static int tps6507x_pmic_dcdc_disable(struct regulator_dev *dev)
291
{
292
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
293 294 295 296 297 298 299
	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;
300 301
	return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
					1 << shift);
302 303
}

304
static int tps6507x_pmic_ldo_enable(struct regulator_dev *dev)
305
{
306
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
307 308 309 310 311 312 313
	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;
314
	return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
315 316
}

317
static int tps6507x_pmic_ldo_disable(struct regulator_dev *dev)
318
{
319
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
320 321 322 323 324 325 326
	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;
327 328
	return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
					1 << shift);
329 330
}

331
static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev)
332
{
333
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
334 335 336 337 338 339 340 341
	int data, dcdc = rdev_get_id(dev);
	u8 reg;

	switch (dcdc) {
	case TPS6507X_DCDC_1:
		reg = TPS6507X_REG_DEFDCDC1;
		break;
	case TPS6507X_DCDC_2:
342 343 344 345
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC2_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC2_LOW;
346 347
		break;
	case TPS6507X_DCDC_3:
348 349 350 351
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC3_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC3_LOW;
352 353 354 355 356
		break;
	default:
		return -EINVAL;
	}

357
	data = tps6507x_pmic_reg_read(tps, reg);
358 359 360 361 362 363 364
	if (data < 0)
		return data;

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

365
static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev,
366 367
					  int min_uV, int max_uV,
					  unsigned *selector)
368
{
369
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
370 371 372 373 374 375 376 377
	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:
378 379 380 381
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC2_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC2_LOW;
382 383
		break;
	case TPS6507X_DCDC_3:
384 385 386 387
		if (tps->info[dcdc]->defdcdc_default)
			reg = TPS6507X_REG_DEFDCDC3_HIGH;
		else
			reg = TPS6507X_REG_DEFDCDC3_LOW;
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
		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;

413 414
	*selector = vsel;

415
	data = tps6507x_pmic_reg_read(tps, reg);
416 417 418 419 420 421
	if (data < 0)
		return data;

	data &= ~TPS6507X_DEFDCDCX_DCDC_MASK;
	data |= vsel;

422
	return tps6507x_pmic_reg_write(tps, reg, data);
423 424
}

425
static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev)
426
{
427
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
428 429 430 431 432 433 434 435 436 437 438 439 440
	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);
	}

441
	data = tps6507x_pmic_reg_read(tps, reg);
442 443 444 445 446 447 448
	if (data < 0)
		return data;

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

449
static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev,
450 451
					 int min_uV, int max_uV,
					 unsigned *selector)
452
{
453
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
	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;

484 485
	*selector = vsel;

486
	data = tps6507x_pmic_reg_read(tps, reg);
487 488 489 490 491 492
	if (data < 0)
		return data;

	data &= ~mask;
	data |= vsel;

493
	return tps6507x_pmic_reg_write(tps, reg, data);
494 495
}

496
static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev,
497 498
					unsigned selector)
{
499
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
500 501 502 503 504 505 506 507 508 509 510
	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;
}

511
static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev,
512 513
					unsigned selector)
{
514
	struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
515 516 517 518 519 520 521 522 523 524 525 526
	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 */
527 528 529 530 531 532 533
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,
534 535 536
};

/* Operations permitted on LDOx */
537 538 539 540 541 542 543
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,
544 545
};

T
Todd Fischer 已提交
546 547
static __devinit
int tps6507x_pmic_probe(struct platform_device *pdev)
548
{
T
Todd Fischer 已提交
549
	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
550
	struct tps_info *info = &tps6507x_pmic_regs[0];
551 552
	struct regulator_init_data *init_data;
	struct regulator_dev *rdev;
553
	struct tps6507x_pmic *tps;
554
	struct tps6507x_board *tps_board;
555
	int i;
556
	int error;
557

558 559 560 561 562
	/**
	 * tps_board points to pmic related constants
	 * coming from the board-evm file.
	 */

T
Todd Fischer 已提交
563
	tps_board = dev_get_platdata(tps6507x_dev->dev);
564 565 566
	if (!tps_board)
		return -EINVAL;

567 568 569 570
	/**
	 * init_data points to array of regulator_init structures
	 * coming from the board-evm file.
	 */
571
	init_data = tps_board->tps6507x_pmic_init_data;
572
	if (!init_data)
573
		return -EINVAL;
574 575 576 577 578 579 580 581

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

	mutex_init(&tps->io_lock);

	/* common for all regulators */
T
Todd Fischer 已提交
582
	tps->mfd = tps6507x_dev;
583 584 585 586

	for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) {
		/* Register the regulators */
		tps->info[i] = info;
587 588 589 590 591 592
		if (init_data->driver_data) {
			struct tps6507x_reg_platform_data *data =
							init_data->driver_data;
			tps->info[i]->defdcdc_default = data->defdcdc_default;
		}

593
		tps->desc[i].name = info->name;
594
		tps->desc[i].id = i;
595
		tps->desc[i].n_voltages = info->table_len;
596
		tps->desc[i].ops = (i > TPS6507X_DCDC_3 ?
597
		&tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
598 599 600 601
		tps->desc[i].type = REGULATOR_VOLTAGE;
		tps->desc[i].owner = THIS_MODULE;

		rdev = regulator_register(&tps->desc[i],
602
					tps6507x_dev->dev, init_data, tps, NULL);
603
		if (IS_ERR(rdev)) {
T
Todd Fischer 已提交
604 605 606
			dev_err(tps6507x_dev->dev,
				"failed to register %s regulator\n",
				pdev->name);
607 608
			error = PTR_ERR(rdev);
			goto fail;
609 610 611 612 613 614
		}

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

T
Todd Fischer 已提交
615
	tps6507x_dev->pmic = tps;
616
	platform_set_drvdata(pdev, tps6507x_dev);
617 618

	return 0;
619 620 621 622 623 624 625

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

	kfree(tps);
	return error;
626 627
}

T
Todd Fischer 已提交
628
static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
629
{
T
Todd Fischer 已提交
630 631
	struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
	struct tps6507x_pmic *tps = tps6507x_dev->pmic;
632 633 634 635 636 637 638 639 640 641
	int i;

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

	kfree(tps);

	return 0;
}

T
Todd Fischer 已提交
642
static struct platform_driver tps6507x_pmic_driver = {
643
	.driver = {
T
Todd Fischer 已提交
644
		.name = "tps6507x-pmic",
645 646
		.owner = THIS_MODULE,
	},
647 648
	.probe = tps6507x_pmic_probe,
	.remove = __devexit_p(tps6507x_pmic_remove),
649 650 651
};

/**
652
 * tps6507x_pmic_init
653 654 655
 *
 * Module init function
 */
656
static int __init tps6507x_pmic_init(void)
657
{
T
Todd Fischer 已提交
658
	return platform_driver_register(&tps6507x_pmic_driver);
659
}
660
subsys_initcall(tps6507x_pmic_init);
661 662

/**
663
 * tps6507x_pmic_cleanup
664 665 666
 *
 * Module exit function
 */
667
static void __exit tps6507x_pmic_cleanup(void)
668
{
T
Todd Fischer 已提交
669
	platform_driver_unregister(&tps6507x_pmic_driver);
670
}
671
module_exit(tps6507x_pmic_cleanup);
672 673 674

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