// SPDX-License-Identifier: GPL-2.0+
//
// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
//
// Copyright 2007, 2008 Wolfson Microelectronics PLC.
//
// Author: Liam Girdwood
// linux@wolfsonmicro.com
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/mfd/wm8350/core.h>
#include <linux/mfd/wm8350/pmic.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
/* Maximum value possible for VSEL */
#define WM8350_DCDC_MAX_VSEL 0x66
/* Microamps */
static const unsigned int isink_cur[] = {
4,
5,
6,
7,
8,
10,
11,
14,
16,
19,
23,
27,
32,
39,
46,
54,
65,
77,
92,
109,
130,
154,
183,
218,
259,
308,
367,
436,
518,
616,
733,
872,
1037,
1233,
1466,
1744,
2073,
2466,
2933,
3487,
4147,
4932,
5865,
6975,
8294,
9864,
11730,
13949,
16589,
19728,
23460,
27899,
33178,
39455,
46920,
55798,
66355,
78910,
93840,
111596,
132710,
157820,
187681,
223191
};
/* turn on ISINK followed by DCDC */
static int wm8350_isink_enable(struct regulator_dev *rdev)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
int isink = rdev_get_id(rdev);
switch (isink) {
case WM8350_ISINK_A:
switch (wm8350->pmic.isink_A_dcdc) {
case WM8350_DCDC_2:
case WM8350_DCDC_5:
wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
WM8350_CS1_ENA);
wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL,
WM8350_CS1_DRIVE);
wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
1 << (wm8350->pmic.isink_A_dcdc -
WM8350_DCDC_1));
break;
default:
return -EINVAL;
}
break;
case WM8350_ISINK_B:
switch (wm8350->pmic.isink_B_dcdc) {
case WM8350_DCDC_2:
case WM8350_DCDC_5:
wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
WM8350_CS2_ENA);
wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL,
WM8350_CS2_DRIVE);
wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
1 << (wm8350->pmic.isink_B_dcdc -
WM8350_DCDC_1));
break;
default:
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int wm8350_isin