forked from Minki/linux
- New Drivers
- Freescale Touch Screen ADC - X-Powers AXP PMIC with RSB - TI TPS65086 Power Management IC (PMIC) - New Device Support - Supply device PCI IDs for Intel Broxton - Fix-ups - Move to clkdev_create() API; intel_quark_i2c_gpio - Complete re-write of TI's TPS65912 Power Management IC (PMIC) - Remove unnecessary function argument; axp20x - Separate out bus related code; axp20x - Coding Style changes; axp20x - Allow more drivers to be compiled as modules - Work around false positive 'used uninitialised' warning; db8500-prcmu - Bug Fixes - Remove do_div(); fsl-imx25-gcq - Fix driver init when built-in; tps65010 - Fix clock-unregister leak; intel-lpss -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW6+LJAAoJEFGvii+H/Hdh8kQP/2AKYzPZiw9fhLufsDPvXO5m BVdLYVyA11oQjQk7/Bh+5Rjz8mR5Tfv4uAJUReC3FOIfC/oJNBfBxYJLDV/P8S0/ KaCEaZrpNmecKrsy+TjmFYtcRa51THAdjlWEUKRks/ZBjwP4YsNnh5reWe+wB7bS NFbCNhpXFvYXaDGH8MRhKqdChzZkxi+lgOBcFCKvUYO5/o6g/ZRUD/0TXUItJDwh F8ps5jImHC1imHeRIKWPNrrZqcYasKmObIhvOKMDcwNQPnjrAWq5QuFH4LFhGQ7d 7NMQrBpaGvZyUNBVtL7ZF1xCJ68wAg/ZvZUkKVkax9ubLbSgf6VXYLQEbq+lyFn7 H9A79xPAGN2nC9HsGnCqW0c0qgTOz0DIkbpuaxAGlzBt0zooc19i3cuUd7LX0NG8 ttLaIP1hX6rgvXSFnF0Ihe3iN5A90LTT3ldbn3A8awyS42vEAbUVL9ivRL21BUbB ilSTO2W05a9HlIVe43o2euytaGvDYX7RbL/g3WcJLF1pA01RCIDQAI5usMpgF3bf fJ7cszll0OVTTb5UzbfrNsxAn4oNtbwMIspMMFe17pbmxqh+4oomM3CkuTrMVQfB pA7Uv0jh/mLCV6P52ZEsNiecn0/l0rID8d/DCHjunr2xBWIOrglzZ7n+vLTJMNJ6 72GVBkYRMLbRm+eph1Tp =gTBA -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Drivers: - Freescale Touch Screen ADC - X-Powers AXP PMIC with RSB - TI TPS65086 Power Management IC (PMIC) New Device Support: - Supply device PCI IDs for Intel Broxton Fix-ups: - Move to clkdev_create() API; intel_quark_i2c_gpio - Complete re-write of TI's TPS65912 Power Management IC (PMIC) - Remove unnecessary function argument; axp20x - Separate out bus related code; axp20x - Coding Style changes; axp20x - Allow more drivers to be compiled as modules - Work around false positive 'used uninitialised' warning; db8500-prcmu Bug Fixes: - Remove do_div(); fsl-imx25-gcq - Fix driver init when built-in; tps65010 - Fix clock-unregister leak; intel-lpss" * tag 'mfd-for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (53 commits) mfd: intel-lpss: Pass I2C configuration via properties on BXT mfd: imx6sx: Add PCIe register definitions for iomuxc gpr mfd: ipaq-micro: Use __maybe_unused to hide pm functions mfd: max77686: Add max77802 to I2C device ID table mfd: max77686: Export OF module alias information mfd: max77686: Allow driver to be built as a module mfd: stmpe: Add the proper PWM resources mfd: tps65090: Set regmap config reg counts properly mfd: syscon: Return ENOTSUPP instead of ENOSYS when disabled mfd: as3711: Set regmap config reg counts properly mfd: rc5t583: Set regmap config reg counts properly gpio: tps65086: Add GPO driver for the TPS65086 PMIC mfd: mt6397: Add platform device ID table mfd: da9063: Fix missing volatile registers in the core regmap_range volatile lists mfd: mt6397: Add MT6323 support to MT6397 driver mfd: mt6397: Add support for different Slave types mfd: mt6397: int_con and int_status may vary in location dt-bindings: mfd: Add bindings for the MediaTek MT6323 PMIC mfd: da9062: Fix missing volatile registers in the core regmap_range volatile lists mfd: Add documentation for ACT8945A DT bindings ...
This commit is contained in:
commit
12e7b0a627
58
Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
Normal file
58
Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
Normal file
@ -0,0 +1,58 @@
|
||||
Freescale i.MX25 ADC GCQ device
|
||||
|
||||
This is a generic conversion queue device that can convert any of the
|
||||
analog inputs using the ADC unit of the i.MX25.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,imx25-gcq".
|
||||
- reg: Should be the register range of the module.
|
||||
- interrupts: Should be the interrupt number of the module.
|
||||
Typically this is <1>.
|
||||
- interrupt-parent: phandle to the tsadc module of the i.MX25.
|
||||
- #address-cells: Should be <1> (setting for the subnodes)
|
||||
- #size-cells: Should be <0> (setting for the subnodes)
|
||||
|
||||
Optional properties:
|
||||
- vref-ext-supply: The regulator supplying the ADC reference voltage.
|
||||
Required when at least one subnode uses the this reference.
|
||||
- vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP.
|
||||
Required when at least one subnode uses this reference.
|
||||
- vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP.
|
||||
Required when at least one subnode uses this reference.
|
||||
|
||||
Sub-nodes:
|
||||
Optionally you can define subnodes which define the reference voltage
|
||||
for the analog inputs.
|
||||
|
||||
Required properties for subnodes:
|
||||
- reg: Should be the number of the analog input.
|
||||
0: xp
|
||||
1: yp
|
||||
2: xn
|
||||
3: yn
|
||||
4: wiper
|
||||
5: inaux0
|
||||
6: inaux1
|
||||
7: inaux2
|
||||
Optional properties for subnodes:
|
||||
- fsl,adc-refp: specifies the positive reference input as defined in
|
||||
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
|
||||
- fsl,adc-refn: specifies the negative reference input as defined in
|
||||
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
|
||||
|
||||
Example:
|
||||
|
||||
adc: adc@50030800 {
|
||||
compatible = "fsl,imx25-gcq";
|
||||
reg = <0x50030800 0x60>;
|
||||
interrupt-parent = <&tscadc>;
|
||||
interrupts = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
inaux@5 {
|
||||
reg = <5>;
|
||||
fsl,adc-refp = <MX25_ADC_REFP_INT>;
|
||||
fsl,adc-refn = <MX25_ADC_REFN_NGND>;
|
||||
};
|
||||
};
|
@ -0,0 +1,35 @@
|
||||
Freescale mx25 TS conversion queue module
|
||||
|
||||
mx25 touchscreen conversion queue module which controls the ADC unit of the
|
||||
mx25 for attached touchscreens.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,imx25-tcq".
|
||||
- reg: Memory range of the device.
|
||||
- interrupts: Should be the interrupt number associated with this module within
|
||||
the tscadc unit (<0>).
|
||||
- interrupt-parent: Should be a phandle to the tscadc unit.
|
||||
- fsl,wires: Should be '<4>' or '<5>'
|
||||
|
||||
Optional properties:
|
||||
- fsl,pen-debounce-ns: Pen debounce time in nanoseconds.
|
||||
- fsl,pen-threshold: Pen-down threshold for the touchscreen. This is a value
|
||||
between 1 and 4096. It is the ratio between the internal reference voltage
|
||||
and the measured voltage after the plate was precharged. Resistence between
|
||||
plates and therefore the voltage decreases with pressure so that a smaller
|
||||
value is equivalent to a higher pressure.
|
||||
- fsl,settling-time-ns: Settling time in nanoseconds. The settling time is before
|
||||
the actual touch detection to wait for an even charge distribution in the
|
||||
plate.
|
||||
|
||||
This device includes two conversion queues which can be added as subnodes.
|
||||
The first queue is for the touchscreen, the second for general purpose ADC.
|
||||
|
||||
Example:
|
||||
tsc: tcq@50030400 {
|
||||
compatible = "fsl,imx25-tcq";
|
||||
reg = <0x50030400 0x60>;
|
||||
interrupt-parent = <&tscadc>;
|
||||
interrupts = <0>;
|
||||
fsl,wires = <4>;
|
||||
};
|
76
Documentation/devicetree/bindings/mfd/act8945a.txt
Normal file
76
Documentation/devicetree/bindings/mfd/act8945a.txt
Normal file
@ -0,0 +1,76 @@
|
||||
Device-Tree bindings for Active-semi ACT8945A MFD driver
|
||||
|
||||
Required properties:
|
||||
- compatible: "active-semi,act8945a".
|
||||
- reg: the I2C slave address for the ACT8945A chip
|
||||
|
||||
The chip exposes two subdevices:
|
||||
- a regulators: see ../regulator/act8945a-regulator.txt
|
||||
- a charger: see ../power/act8945a-charger.txt
|
||||
|
||||
Example:
|
||||
pmic@5b {
|
||||
compatible = "active-semi,act8945a";
|
||||
reg = <0x5b>;
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_charger_chglev>;
|
||||
active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>;
|
||||
active-semi,input-voltage-threshold-microvolt = <6600>;
|
||||
active-semi,precondition-timeout = <40>;
|
||||
active-semi,total-timeout = <3>;
|
||||
|
||||
active-semi,vsel-high;
|
||||
|
||||
regulators {
|
||||
vdd_1v35_reg: REG_DCDC1 {
|
||||
regulator-name = "VDD_1V35";
|
||||
regulator-min-microvolt = <1350000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_1v2_reg: REG_DCDC2 {
|
||||
regulator-name = "VDD_1V2";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_3v3_reg: REG_DCDC3 {
|
||||
regulator-name = "VDD_3V3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_fuse_reg: REG_LDO1 {
|
||||
regulator-name = "VDD_FUSE";
|
||||
regulator-min-microvolt = <2500000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_3v3_lp_reg: REG_LDO2 {
|
||||
regulator-name = "VDD_3V3_LP";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_led_reg: REG_LDO3 {
|
||||
regulator-name = "VDD_LED";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_sdhc_1v8_reg: REG_LDO4 {
|
||||
regulator-name = "VDD_SDHC_1V8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
@ -5,11 +5,12 @@ axp152 (X-Powers)
|
||||
axp202 (X-Powers)
|
||||
axp209 (X-Powers)
|
||||
axp221 (X-Powers)
|
||||
axp223 (X-Powers)
|
||||
|
||||
Required properties:
|
||||
- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209",
|
||||
"x-powers,axp221"
|
||||
- reg: The I2C slave address for the AXP chip
|
||||
"x-powers,axp221", "x-powers,axp223"
|
||||
- reg: The I2C slave address or RSB hardware address for the AXP chip
|
||||
- interrupt-parent: The parent interrupt controller
|
||||
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
|
||||
- interrupt-controller: The PMIC has its own internal IRQs
|
||||
@ -51,7 +52,7 @@ LDO3 : LDO : ldo3in-supply
|
||||
LDO4 : LDO : ldo24in-supply : shared supply
|
||||
LDO5 : LDO : ldo5in-supply
|
||||
|
||||
AXP221 regulators, type, and corresponding input supply names:
|
||||
AXP221/AXP223 regulators, type, and corresponding input supply names:
|
||||
|
||||
Regulator Type Supply Name Notes
|
||||
--------- ---- ----------- -----
|
||||
|
47
Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
Normal file
47
Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
Normal file
@ -0,0 +1,47 @@
|
||||
Freescale MX25 ADC/TSC MultiFunction Device (MFD)
|
||||
|
||||
This device combines two general purpose conversion queues one used for general
|
||||
ADC and the other used for touchscreens.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,imx25-tsadc".
|
||||
- reg: Start address and size of the memory area of
|
||||
the device
|
||||
- interrupts: Interrupt for this device
|
||||
(See: ../interrupt-controller/interrupts.txt)
|
||||
- clocks: An 'ipg' clock (See: ../clock/clock-bindings.txt)
|
||||
- interrupt-controller: This device is an interrupt controller. It
|
||||
controls the interrupts of both
|
||||
conversion queues.
|
||||
- #interrupt-cells: Should be '<1>'.
|
||||
- #address-cells: Should be '<1>'.
|
||||
- #size-cells: Should be '<1>'.
|
||||
|
||||
This device includes two conversion queues which can be added as subnodes.
|
||||
The first queue is for the touchscreen, the second for general purpose ADC.
|
||||
|
||||
Example:
|
||||
tscadc: tscadc@50030000 {
|
||||
compatible = "fsl,imx25-tsadc";
|
||||
reg = <0x50030000 0xc>;
|
||||
interrupts = <46>;
|
||||
clocks = <&clks 119>;
|
||||
clock-names = "ipg";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
tsc: tcq@50030400 {
|
||||
compatible = "fsl,imx25-tcq";
|
||||
reg = <0x50030400 0x60>;
|
||||
...
|
||||
};
|
||||
|
||||
adc: gcq@50030800 {
|
||||
compatible = "fsl,imx25-gcq";
|
||||
reg = <0x50030800 0x60>;
|
||||
...
|
||||
};
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
MediaTek MT6397 Multifunction Device Driver
|
||||
MediaTek MT6397/MT6323 Multifunction Device Driver
|
||||
|
||||
MT6397 is a multifunction device with the following sub modules:
|
||||
MT6397/MT6323 is a multifunction device with the following sub modules:
|
||||
- Regulator
|
||||
- RTC
|
||||
- Audio codec
|
||||
@ -8,14 +8,14 @@ MT6397 is a multifunction device with the following sub modules:
|
||||
- Clock
|
||||
|
||||
It is interfaced to host controller using SPI interface by a proprietary hardware
|
||||
called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap.
|
||||
called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
|
||||
See the following for pwarp node definitions:
|
||||
Documentation/devicetree/bindings/soc/pwrap.txt
|
||||
|
||||
This document describes the binding for MFD device and its sub module.
|
||||
|
||||
Required properties:
|
||||
compatible: "mediatek,mt6397"
|
||||
compatible: "mediatek,mt6397" or "mediatek,mt6323"
|
||||
|
||||
Optional subnodes:
|
||||
|
||||
@ -26,6 +26,8 @@ Optional subnodes:
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-regulator"
|
||||
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
|
||||
- compatible: "mediatek,mt6323-regulator"
|
||||
see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
|
||||
- codec
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-codec"
|
||||
|
55
Documentation/devicetree/bindings/mfd/tps65086.txt
Normal file
55
Documentation/devicetree/bindings/mfd/tps65086.txt
Normal file
@ -0,0 +1,55 @@
|
||||
* TPS65086 Power Management Integrated Circuit (PMIC) bindings
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "ti,tps65086".
|
||||
- reg : I2C slave address.
|
||||
- interrupt-parent : Phandle to the parent interrupt controller.
|
||||
- interrupts : The interrupt line the device is connected to.
|
||||
- interrupt-controller : Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells : The number of cells to describe an IRQ, should be 2.
|
||||
The first cell is the IRQ number.
|
||||
The second cell is the flags, encoded as trigger
|
||||
masks from ../interrupt-controller/interrupts.txt.
|
||||
- gpio-controller : Marks the device node as a GPIO Controller.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify flags.
|
||||
See ../gpio/gpio.txt for more information.
|
||||
- regulators: : List of child nodes that specify the regulator
|
||||
initialization data. Child nodes must be named
|
||||
after their hardware counterparts: buck[1-6],
|
||||
ldoa[1-3], swa1, swb[1-2], and vtt. Each child
|
||||
node is defined using the standard binding for
|
||||
regulators and the optional regulator properties
|
||||
defined below.
|
||||
|
||||
Optional regulator properties:
|
||||
- ti,regulator-step-size-25mv : This is applicable for buck[1,2,6], set this
|
||||
if the regulator is factory set with a 25mv
|
||||
step voltage mapping.
|
||||
- ti,regulator-decay : This is applicable for buck[1-6], set this if
|
||||
the output needs to decay, default is for
|
||||
the output to slew down.
|
||||
|
||||
Example:
|
||||
|
||||
pmic: tps65086@5e {
|
||||
compatible = "ti,tps65086";
|
||||
reg = <0x5e>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
regulators {
|
||||
buck1 {
|
||||
regulator-name = "vcc1";
|
||||
regulator-min-microvolt = <1600000>;
|
||||
regulator-max-microvolt = <1600000>;
|
||||
regulator-boot-on;
|
||||
ti,regulator-decay;
|
||||
ti,regulator-step-size-25mv;
|
||||
};
|
||||
};
|
||||
};
|
@ -898,6 +898,12 @@ config GPIO_TIMBERDALE
|
||||
---help---
|
||||
Add support for the GPIO IP in the timberdale FPGA.
|
||||
|
||||
config GPIO_TPS65086
|
||||
tristate "TI TPS65086 GPO"
|
||||
depends on MFD_TPS65086
|
||||
help
|
||||
This driver supports the GPO on TI TPS65086x PMICs.
|
||||
|
||||
config GPIO_TPS65218
|
||||
tristate "TPS65218 GPIO"
|
||||
depends on MFD_TPS65218
|
||||
|
@ -99,6 +99,7 @@ obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
|
||||
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
|
||||
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
|
||||
obj-$(CONFIG_GPIO_TPS65086) += gpio-tps65086.o
|
||||
obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
|
||||
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
|
||||
|
139
drivers/gpio/gpio-tps65086.c
Normal file
139
drivers/gpio/gpio-tps65086.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Andrew F. Davis <afd@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether expressed or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License version 2 for more details.
|
||||
*
|
||||
* Based on the TPS65912 driver
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/mfd/tps65086.h>
|
||||
|
||||
struct tps65086_gpio {
|
||||
struct gpio_chip chip;
|
||||
struct tps65086 *tps;
|
||||
};
|
||||
|
||||
static int tps65086_gpio_get_direction(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
{
|
||||
/* This device is output only */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65086_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
{
|
||||
/* This device is output only */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int tps65086_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct tps65086_gpio *gpio = gpiochip_get_data(chip);
|
||||
|
||||
/* Set the initial value */
|
||||
regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
|
||||
BIT(4 + offset), value ? BIT(4 + offset) : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65086_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct tps65086_gpio *gpio = gpiochip_get_data(chip);
|
||||
int ret, val;
|
||||
|
||||
ret = regmap_read(gpio->tps->regmap, TPS65086_GPOCTRL, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return val & BIT(4 + offset);
|
||||
}
|
||||
|
||||
static void tps65086_gpio_set(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
struct tps65086_gpio *gpio = gpiochip_get_data(chip);
|
||||
|
||||
regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
|
||||
BIT(4 + offset), value ? BIT(4 + offset) : 0);
|
||||
}
|
||||
|
||||
static struct gpio_chip template_chip = {
|
||||
.label = "tps65086-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
.get_direction = tps65086_gpio_get_direction,
|
||||
.direction_input = tps65086_gpio_direction_input,
|
||||
.direction_output = tps65086_gpio_direction_output,
|
||||
.get = tps65086_gpio_get,
|
||||
.set = tps65086_gpio_set,
|
||||
.base = -1,
|
||||
.ngpio = 4,
|
||||
.can_sleep = true,
|
||||
};
|
||||
|
||||
static int tps65086_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65086_gpio *gpio;
|
||||
int ret;
|
||||
|
||||
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
|
||||
if (!gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, gpio);
|
||||
|
||||
gpio->tps = dev_get_drvdata(pdev->dev.parent);
|
||||
gpio->chip = template_chip;
|
||||
gpio->chip.parent = gpio->tps->dev;
|
||||
|
||||
ret = gpiochip_add_data(&gpio->chip, gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65086_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65086_gpio *gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&gpio->chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id tps65086_gpio_id_table[] = {
|
||||
{ "tps65086-gpio", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, tps65086_gpio_id_table);
|
||||
|
||||
static struct platform_driver tps65086_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "tps65086-gpio",
|
||||
},
|
||||
.probe = tps65086_gpio_probe,
|
||||
.remove = tps65086_gpio_remove,
|
||||
.id_table = tps65086_gpio_id_table,
|
||||
};
|
||||
module_platform_driver(tps65086_gpio_driver);
|
||||
|
||||
MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
|
||||
MODULE_DESCRIPTION("TPS65086 GPIO driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -194,6 +194,13 @@ config EXYNOS_ADC
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called exynos_adc.
|
||||
|
||||
config FSL_MX25_ADC
|
||||
tristate "Freescale MX25 ADC driver"
|
||||
depends on MFD_MX25_TSADC
|
||||
help
|
||||
Generic Conversion Queue driver used for general purpose ADC in the
|
||||
MX25. This driver supports single measurements using the MX25 ADC.
|
||||
|
||||
config HI8435
|
||||
tristate "Holt Integrated Circuits HI-8435 threshold detector"
|
||||
select IIO_TRIGGERED_EVENT
|
||||
|
@ -20,6 +20,7 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
|
||||
obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
|
||||
obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
|
||||
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
|
||||
obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
|
||||
obj-$(CONFIG_HI8435) += hi8435.o
|
||||
obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
|
||||
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
|
||||
|
417
drivers/iio/adc/fsl-imx25-gcq.c
Normal file
417
drivers/iio/adc/fsl-imx25-gcq.c
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This is the driver for the imx25 GCQ (Generic Conversion Queue)
|
||||
* connected to the imx25 ADC.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/imx25-tsadc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
|
||||
|
||||
static const char * const driver_name = "mx25-gcq";
|
||||
|
||||
enum mx25_gcq_cfgs {
|
||||
MX25_CFG_XP = 0,
|
||||
MX25_CFG_YP,
|
||||
MX25_CFG_XN,
|
||||
MX25_CFG_YN,
|
||||
MX25_CFG_WIPER,
|
||||
MX25_CFG_INAUX0,
|
||||
MX25_CFG_INAUX1,
|
||||
MX25_CFG_INAUX2,
|
||||
MX25_NUM_CFGS,
|
||||
};
|
||||
|
||||
struct mx25_gcq_priv {
|
||||
struct regmap *regs;
|
||||
struct completion completed;
|
||||
struct clk *clk;
|
||||
int irq;
|
||||
struct regulator *vref[4];
|
||||
u32 channel_vref_mv[MX25_NUM_CFGS];
|
||||
};
|
||||
|
||||
#define MX25_CQG_CHAN(chan, id) {\
|
||||
.type = IIO_VOLTAGE,\
|
||||
.indexed = 1,\
|
||||
.channel = chan,\
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE),\
|
||||
.datasheet_name = id,\
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec mx25_gcq_channels[MX25_NUM_CFGS] = {
|
||||
MX25_CQG_CHAN(MX25_CFG_XP, "xp"),
|
||||
MX25_CQG_CHAN(MX25_CFG_YP, "yp"),
|
||||
MX25_CQG_CHAN(MX25_CFG_XN, "xn"),
|
||||
MX25_CQG_CHAN(MX25_CFG_YN, "yn"),
|
||||
MX25_CQG_CHAN(MX25_CFG_WIPER, "wiper"),
|
||||
MX25_CQG_CHAN(MX25_CFG_INAUX0, "inaux0"),
|
||||
MX25_CQG_CHAN(MX25_CFG_INAUX1, "inaux1"),
|
||||
MX25_CQG_CHAN(MX25_CFG_INAUX2, "inaux2"),
|
||||
};
|
||||
|
||||
static const char * const mx25_gcq_refp_names[] = {
|
||||
[MX25_ADC_REFP_YP] = "yp",
|
||||
[MX25_ADC_REFP_XP] = "xp",
|
||||
[MX25_ADC_REFP_INT] = "int",
|
||||
[MX25_ADC_REFP_EXT] = "ext",
|
||||
};
|
||||
|
||||
static irqreturn_t mx25_gcq_irq(int irq, void *data)
|
||||
{
|
||||
struct mx25_gcq_priv *priv = data;
|
||||
u32 stats;
|
||||
|
||||
regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
|
||||
|
||||
if (stats & MX25_ADCQ_SR_EOQ) {
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_MR,
|
||||
MX25_ADCQ_MR_EOQ_IRQ, MX25_ADCQ_MR_EOQ_IRQ);
|
||||
complete(&priv->completed);
|
||||
}
|
||||
|
||||
/* Disable conversion queue run */
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
|
||||
|
||||
/* Acknowledge all possible irqs */
|
||||
regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
|
||||
MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
|
||||
MX25_ADCQ_SR_EOQ | MX25_ADCQ_SR_PD);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mx25_gcq_get_raw_value(struct device *dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
struct mx25_gcq_priv *priv,
|
||||
int *val)
|
||||
{
|
||||
long timeout;
|
||||
u32 data;
|
||||
|
||||
/* Setup the configuration we want to use */
|
||||
regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
|
||||
MX25_ADCQ_ITEM(0, chan->channel));
|
||||
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0);
|
||||
|
||||
/* Trigger queue for one run */
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS,
|
||||
MX25_ADCQ_CR_FQS);
|
||||
|
||||
timeout = wait_for_completion_interruptible_timeout(
|
||||
&priv->completed, MX25_GCQ_TIMEOUT);
|
||||
if (timeout < 0) {
|
||||
dev_err(dev, "ADC wait for measurement failed\n");
|
||||
return timeout;
|
||||
} else if (timeout == 0) {
|
||||
dev_err(dev, "ADC timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
regmap_read(priv->regs, MX25_ADCQ_FIFO, &data);
|
||||
|
||||
*val = MX25_ADCQ_FIFO_DATA(data);
|
||||
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
|
||||
static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val,
|
||||
int *val2, long mask)
|
||||
{
|
||||
struct mx25_gcq_priv *priv = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return ret;
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = priv->channel_vref_mv[chan->channel];
|
||||
*val2 = 12;
|
||||
return IIO_VAL_FRACTIONAL_LOG2;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct iio_info mx25_gcq_iio_info = {
|
||||
.read_raw = mx25_gcq_read_raw,
|
||||
};
|
||||
|
||||
static const struct regmap_config mx25_gcq_regconfig = {
|
||||
.max_register = 0x5c,
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
|
||||
struct mx25_gcq_priv *priv)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *child;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int refp_used[4] = {};
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* Setup all configurations registers with a default conversion
|
||||
* configuration for each input
|
||||
*/
|
||||
for (i = 0; i < MX25_NUM_CFGS; ++i)
|
||||
regmap_write(priv->regs, MX25_ADCQ_CFG(i),
|
||||
MX25_ADCQ_CFG_YPLL_OFF |
|
||||
MX25_ADCQ_CFG_XNUR_OFF |
|
||||
MX25_ADCQ_CFG_XPUL_OFF |
|
||||
MX25_ADCQ_CFG_REFP_INT |
|
||||
MX25_ADCQ_CFG_IN(i) |
|
||||
MX25_ADCQ_CFG_REFN_NGND2);
|
||||
|
||||
/*
|
||||
* First get all regulators to store them in channel_vref_mv if
|
||||
* necessary. Later we use that information for proper IIO scale
|
||||
* information.
|
||||
*/
|
||||
priv->vref[MX25_ADC_REFP_INT] = NULL;
|
||||
priv->vref[MX25_ADC_REFP_EXT] =
|
||||
devm_regulator_get_optional(&pdev->dev, "vref-ext");
|
||||
priv->vref[MX25_ADC_REFP_XP] =
|
||||
devm_regulator_get_optional(&pdev->dev, "vref-xp");
|
||||
priv->vref[MX25_ADC_REFP_YP] =
|
||||
devm_regulator_get_optional(&pdev->dev, "vref-yp");
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
u32 reg;
|
||||
u32 refp = MX25_ADCQ_CFG_REFP_INT;
|
||||
u32 refn = MX25_ADCQ_CFG_REFN_NGND2;
|
||||
|
||||
ret = of_property_read_u32(child, "reg", ®);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get reg property\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (reg >= MX25_NUM_CFGS) {
|
||||
dev_err(dev,
|
||||
"reg value is greater than the number of available configuration registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_property_read_u32(child, "fsl,adc-refp", &refp);
|
||||
of_property_read_u32(child, "fsl,adc-refn", &refn);
|
||||
|
||||
switch (refp) {
|
||||
case MX25_ADC_REFP_EXT:
|
||||
case MX25_ADC_REFP_XP:
|
||||
case MX25_ADC_REFP_YP:
|
||||
if (IS_ERR(priv->vref[refp])) {
|
||||
dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.",
|
||||
mx25_gcq_refp_names[refp]);
|
||||
return PTR_ERR(priv->vref[refp]);
|
||||
}
|
||||
priv->channel_vref_mv[reg] =
|
||||
regulator_get_voltage(priv->vref[refp]);
|
||||
/* Conversion from uV to mV */
|
||||
priv->channel_vref_mv[reg] /= 1000;
|
||||
break;
|
||||
case MX25_ADC_REFP_INT:
|
||||
priv->channel_vref_mv[reg] = 2500;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid positive reference %d\n", refp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
++refp_used[refp];
|
||||
|
||||
/*
|
||||
* Shift the read values to the correct positions within the
|
||||
* register.
|
||||
*/
|
||||
refp = MX25_ADCQ_CFG_REFP(refp);
|
||||
refn = MX25_ADCQ_CFG_REFN(refn);
|
||||
|
||||
if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
|
||||
dev_err(dev, "Invalid fsl,adc-refp property value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
|
||||
dev_err(dev, "Invalid fsl,adc-refn property value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg),
|
||||
MX25_ADCQ_CFG_REFP_MASK |
|
||||
MX25_ADCQ_CFG_REFN_MASK,
|
||||
refp | refn);
|
||||
}
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST,
|
||||
MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST);
|
||||
|
||||
regmap_write(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_PDMSK | MX25_ADCQ_CR_QSM_FQS);
|
||||
|
||||
/* Remove unused regulators */
|
||||
for (i = 0; i != 4; ++i) {
|
||||
if (!refp_used[i]) {
|
||||
if (!IS_ERR_OR_NULL(priv->vref[i]))
|
||||
devm_regulator_put(priv->vref[i]);
|
||||
priv->vref[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mx25_gcq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_dev *indio_dev;
|
||||
struct mx25_gcq_priv *priv;
|
||||
struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
void __iomem *mem;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = iio_priv(indio_dev);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mem = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(mem))
|
||||
return PTR_ERR(mem);
|
||||
|
||||
priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig);
|
||||
if (IS_ERR(priv->regs)) {
|
||||
dev_err(dev, "Failed to initialize regmap\n");
|
||||
return PTR_ERR(priv->regs);
|
||||
}
|
||||
|
||||
init_completion(&priv->completed);
|
||||
|
||||
ret = mx25_gcq_setup_cfgs(pdev, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i != 4; ++i) {
|
||||
if (!priv->vref[i])
|
||||
continue;
|
||||
|
||||
ret = regulator_enable(priv->vref[i]);
|
||||
if (ret)
|
||||
goto err_regulator_disable;
|
||||
}
|
||||
|
||||
priv->clk = tsadc->clk;
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable clock\n");
|
||||
goto err_vref_disable;
|
||||
}
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq <= 0) {
|
||||
dev_err(dev, "Failed to get IRQ\n");
|
||||
ret = priv->irq;
|
||||
if (!ret)
|
||||
ret = -ENXIO;
|
||||
goto err_clk_unprepare;
|
||||
}
|
||||
|
||||
ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed requesting IRQ\n");
|
||||
goto err_clk_unprepare;
|
||||
}
|
||||
|
||||
indio_dev->dev.parent = &pdev->dev;
|
||||
indio_dev->channels = mx25_gcq_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels);
|
||||
indio_dev->info = &mx25_gcq_iio_info;
|
||||
indio_dev->name = driver_name;
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register iio device\n");
|
||||
goto err_irq_free;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq_free:
|
||||
free_irq(priv->irq, priv);
|
||||
err_clk_unprepare:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
err_vref_disable:
|
||||
i = 4;
|
||||
err_regulator_disable:
|
||||
for (; i-- > 0;) {
|
||||
if (priv->vref[i])
|
||||
regulator_disable(priv->vref[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mx25_gcq_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
struct mx25_gcq_priv *priv = iio_priv(indio_dev);
|
||||
int i;
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
free_irq(priv->irq, priv);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
for (i = 4; i-- > 0;) {
|
||||
if (priv->vref[i])
|
||||
regulator_disable(priv->vref[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mx25_gcq_ids[] = {
|
||||
{ .compatible = "fsl,imx25-gcq", },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver mx25_gcq_driver = {
|
||||
.driver = {
|
||||
.name = "mx25-gcq",
|
||||
.of_match_table = mx25_gcq_ids,
|
||||
},
|
||||
.probe = mx25_gcq_probe,
|
||||
.remove = mx25_gcq_remove,
|
||||
};
|
||||
module_platform_driver(mx25_gcq_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ADC driver for Freescale mx25");
|
||||
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -833,6 +833,15 @@ config TOUCHSCREEN_USB_COMPOSITE
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called usbtouchscreen.
|
||||
|
||||
config TOUCHSCREEN_MX25
|
||||
tristate "Freescale i.MX25 touchscreen input driver"
|
||||
depends on MFD_MX25_TSADC
|
||||
help
|
||||
Enable support for touchscreen connected to your i.MX25.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called fsl-imx25-tcq.
|
||||
|
||||
config TOUCHSCREEN_MC13783
|
||||
tristate "Freescale MC13783 touchscreen input driver"
|
||||
depends on MFD_MC13XXX
|
||||
|
@ -46,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MX25) += fsl-imx25-tcq.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MELFAS_MIP4) += melfas_mip4.o
|
||||
|
596
drivers/input/touchscreen/fsl-imx25-tcq.c
Normal file
596
drivers/input/touchscreen/fsl-imx25-tcq.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* Based on driver from 2011:
|
||||
* Juergen Beisert, Pengutronix <kernel@pengutronix.de>
|
||||
*
|
||||
* This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
|
||||
* connected to the imx25 ADC.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/imx25-tsadc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const char mx25_tcq_name[] = "mx25-tcq";
|
||||
|
||||
enum mx25_tcq_mode {
|
||||
MX25_TS_4WIRE,
|
||||
};
|
||||
|
||||
struct mx25_tcq_priv {
|
||||
struct regmap *regs;
|
||||
struct regmap *core_regs;
|
||||
struct input_dev *idev;
|
||||
enum mx25_tcq_mode mode;
|
||||
unsigned int pen_threshold;
|
||||
unsigned int sample_count;
|
||||
unsigned int expected_samples;
|
||||
unsigned int pen_debounce;
|
||||
unsigned int settling_time;
|
||||
struct clk *clk;
|
||||
int irq;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static struct regmap_config mx25_tcq_regconfig = {
|
||||
.fast_io = true,
|
||||
.max_register = 0x5c,
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static const struct of_device_id mx25_tcq_ids[] = {
|
||||
{ .compatible = "fsl,imx25-tcq", },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
#define TSC_4WIRE_PRE_INDEX 0
|
||||
#define TSC_4WIRE_X_INDEX 1
|
||||
#define TSC_4WIRE_Y_INDEX 2
|
||||
#define TSC_4WIRE_POST_INDEX 3
|
||||
#define TSC_4WIRE_LEAVE 4
|
||||
|
||||
#define MX25_TSC_DEF_THRESHOLD 80
|
||||
#define TSC_MAX_SAMPLES 16
|
||||
|
||||
#define MX25_TSC_REPEAT_WAIT 14
|
||||
|
||||
enum mx25_adc_configurations {
|
||||
MX25_CFG_PRECHARGE = 0,
|
||||
MX25_CFG_TOUCH_DETECT,
|
||||
MX25_CFG_X_MEASUREMENT,
|
||||
MX25_CFG_Y_MEASUREMENT,
|
||||
};
|
||||
|
||||
#define MX25_PRECHARGE_VALUE (\
|
||||
MX25_ADCQ_CFG_YPLL_OFF | \
|
||||
MX25_ADCQ_CFG_XNUR_OFF | \
|
||||
MX25_ADCQ_CFG_XPUL_HIGH | \
|
||||
MX25_ADCQ_CFG_REFP_INT | \
|
||||
MX25_ADCQ_CFG_IN_XP | \
|
||||
MX25_ADCQ_CFG_REFN_NGND2 | \
|
||||
MX25_ADCQ_CFG_IGS)
|
||||
|
||||
#define MX25_TOUCH_DETECT_VALUE (\
|
||||
MX25_ADCQ_CFG_YNLR | \
|
||||
MX25_ADCQ_CFG_YPLL_OFF | \
|
||||
MX25_ADCQ_CFG_XNUR_OFF | \
|
||||
MX25_ADCQ_CFG_XPUL_OFF | \
|
||||
MX25_ADCQ_CFG_REFP_INT | \
|
||||
MX25_ADCQ_CFG_IN_XP | \
|
||||
MX25_ADCQ_CFG_REFN_NGND2 | \
|
||||
MX25_ADCQ_CFG_PENIACK)
|
||||
|
||||
static void imx25_setup_queue_cfgs(struct mx25_tcq_priv *priv,
|
||||
unsigned int settling_cnt)
|
||||
{
|
||||
u32 precharge_cfg =
|
||||
MX25_PRECHARGE_VALUE |
|
||||
MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
|
||||
u32 touch_detect_cfg =
|
||||
MX25_TOUCH_DETECT_VALUE |
|
||||
MX25_ADCQ_CFG_NOS(1) |
|
||||
MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
|
||||
|
||||
regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg);
|
||||
|
||||
/* PRECHARGE */
|
||||
regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE),
|
||||
precharge_cfg);
|
||||
|
||||
/* TOUCH_DETECT */
|
||||
regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT),
|
||||
touch_detect_cfg);
|
||||
|
||||
/* X Measurement */
|
||||
regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT),
|
||||
MX25_ADCQ_CFG_YPLL_OFF |
|
||||
MX25_ADCQ_CFG_XNUR_LOW |
|
||||
MX25_ADCQ_CFG_XPUL_HIGH |
|
||||
MX25_ADCQ_CFG_REFP_XP |
|
||||
MX25_ADCQ_CFG_IN_YP |
|
||||
MX25_ADCQ_CFG_REFN_XN |
|
||||
MX25_ADCQ_CFG_NOS(priv->sample_count) |
|
||||
MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
|
||||
|
||||
/* Y Measurement */
|
||||
regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT),
|
||||
MX25_ADCQ_CFG_YNLR |
|
||||
MX25_ADCQ_CFG_YPLL_HIGH |
|
||||
MX25_ADCQ_CFG_XNUR_OFF |
|
||||
MX25_ADCQ_CFG_XPUL_OFF |
|
||||
MX25_ADCQ_CFG_REFP_YP |
|
||||
MX25_ADCQ_CFG_IN_XP |
|
||||
MX25_ADCQ_CFG_REFN_YN |
|
||||
MX25_ADCQ_CFG_NOS(priv->sample_count) |
|
||||
MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
|
||||
|
||||
/* Enable the touch detection right now */
|
||||
regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg |
|
||||
MX25_ADCQ_CFG_IGS);
|
||||
}
|
||||
|
||||
static int imx25_setup_queue_4wire(struct mx25_tcq_priv *priv,
|
||||
unsigned settling_cnt, int *items)
|
||||
{
|
||||
imx25_setup_queue_cfgs(priv, settling_cnt);
|
||||
|
||||
/* Setup the conversion queue */
|
||||
regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
|
||||
MX25_ADCQ_ITEM(0, MX25_CFG_PRECHARGE) |
|
||||
MX25_ADCQ_ITEM(1, MX25_CFG_TOUCH_DETECT) |
|
||||
MX25_ADCQ_ITEM(2, MX25_CFG_X_MEASUREMENT) |
|
||||
MX25_ADCQ_ITEM(3, MX25_CFG_Y_MEASUREMENT) |
|
||||
MX25_ADCQ_ITEM(4, MX25_CFG_PRECHARGE) |
|
||||
MX25_ADCQ_ITEM(5, MX25_CFG_TOUCH_DETECT));
|
||||
|
||||
/*
|
||||
* We measure X/Y with 'sample_count' number of samples and execute a
|
||||
* touch detection twice, with 1 sample each
|
||||
*/
|
||||
priv->expected_samples = priv->sample_count * 2 + 2;
|
||||
*items = 6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mx25_tcq_disable_touch_irq(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK,
|
||||
MX25_ADCQ_CR_PDMSK);
|
||||
}
|
||||
|
||||
static void mx25_tcq_enable_touch_irq(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0);
|
||||
}
|
||||
|
||||
static void mx25_tcq_disable_fifo_irq(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ,
|
||||
MX25_ADCQ_MR_FDRY_IRQ);
|
||||
}
|
||||
|
||||
static void mx25_tcq_enable_fifo_irq(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0);
|
||||
}
|
||||
|
||||
static void mx25_tcq_force_queue_start(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_FQS,
|
||||
MX25_ADCQ_CR_FQS);
|
||||
}
|
||||
|
||||
static void mx25_tcq_force_queue_stop(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_FQS, 0);
|
||||
}
|
||||
|
||||
static void mx25_tcq_fifo_reset(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
u32 tcqcr;
|
||||
|
||||
regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr);
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST,
|
||||
MX25_ADCQ_CR_FRST);
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0);
|
||||
regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr);
|
||||
}
|
||||
|
||||
static void mx25_tcq_re_enable_touch_detection(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
/* stop the queue from looping */
|
||||
mx25_tcq_force_queue_stop(priv);
|
||||
|
||||
/* for a clean touch detection, preload the X plane */
|
||||
regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE);
|
||||
|
||||
/* waste some time now to pre-load the X plate to high voltage */
|
||||
mx25_tcq_fifo_reset(priv);
|
||||
|
||||
/* re-enable the detection right now */
|
||||
regmap_write(priv->core_regs, MX25_TSC_TICR,
|
||||
MX25_TOUCH_DETECT_VALUE | MX25_ADCQ_CFG_IGS);
|
||||
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD,
|
||||
MX25_ADCQ_SR_PD);
|
||||
|
||||
/* enable the pen down event to be a source for the interrupt */
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0);
|
||||
|
||||
/* lets fire the next IRQ if someone touches the touchscreen */
|
||||
mx25_tcq_enable_touch_irq(priv);
|
||||
}
|
||||
|
||||
static void mx25_tcq_create_event_for_4wire(struct mx25_tcq_priv *priv,
|
||||
u32 *sample_buf,
|
||||
unsigned int samples)
|
||||
{
|
||||
unsigned int x_pos = 0;
|
||||
unsigned int y_pos = 0;
|
||||
unsigned int touch_pre = 0;
|
||||
unsigned int touch_post = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < samples; i++) {
|
||||
unsigned int index = MX25_ADCQ_FIFO_ID(sample_buf[i]);
|
||||
unsigned int val = MX25_ADCQ_FIFO_DATA(sample_buf[i]);
|
||||
|
||||
switch (index) {
|
||||
case 1:
|
||||
touch_pre = val;
|
||||
break;
|
||||
case 2:
|
||||
x_pos = val;
|
||||
break;
|
||||
case 3:
|
||||
y_pos = val;
|
||||
break;
|
||||
case 5:
|
||||
touch_post = val;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n",
|
||||
index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (samples != 0) {
|
||||
/*
|
||||
* only if both touch measures are below a threshold,
|
||||
* the position is valid
|
||||
*/
|
||||
if (touch_pre < priv->pen_threshold &&
|
||||
touch_post < priv->pen_threshold) {
|
||||
/* valid samples, generate a report */
|
||||
x_pos /= priv->sample_count;
|
||||
y_pos /= priv->sample_count;
|
||||
input_report_abs(priv->idev, ABS_X, x_pos);
|
||||
input_report_abs(priv->idev, ABS_Y, y_pos);
|
||||
input_report_key(priv->idev, BTN_TOUCH, 1);
|
||||
input_sync(priv->idev);
|
||||
|
||||
/* get next sample */
|
||||
mx25_tcq_enable_fifo_irq(priv);
|
||||
} else if (touch_pre >= priv->pen_threshold &&
|
||||
touch_post >= priv->pen_threshold) {
|
||||
/*
|
||||
* if both samples are invalid,
|
||||
* generate a release report
|
||||
*/
|
||||
input_report_key(priv->idev, BTN_TOUCH, 0);
|
||||
input_sync(priv->idev);
|
||||
mx25_tcq_re_enable_touch_detection(priv);
|
||||
} else {
|
||||
/*
|
||||
* if only one of both touch measurements are
|
||||
* below the threshold, still some bouncing
|
||||
* happens. Take additional samples in this
|
||||
* case to be sure
|
||||
*/
|
||||
mx25_tcq_enable_fifo_irq(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t mx25_tcq_irq_thread(int irq, void *dev_id)
|
||||
{
|
||||
struct mx25_tcq_priv *priv = dev_id;
|
||||
u32 sample_buf[TSC_MAX_SAMPLES];
|
||||
unsigned int samples;
|
||||
u32 stats;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Check how many samples are available. We always have to read exactly
|
||||
* sample_count samples from the fifo, or a multiple of sample_count.
|
||||
* Otherwise we mixup samples into different touch events.
|
||||
*/
|
||||
regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
|
||||
samples = MX25_ADCQ_SR_FDN(stats);
|
||||
samples -= samples % priv->sample_count;
|
||||
|
||||
if (!samples)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
for (i = 0; i != samples; ++i)
|
||||
regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]);
|
||||
|
||||
mx25_tcq_create_event_for_4wire(priv, sample_buf, samples);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t mx25_tcq_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct mx25_tcq_priv *priv = dev_id;
|
||||
u32 stat;
|
||||
int ret = IRQ_HANDLED;
|
||||
|
||||
regmap_read(priv->regs, MX25_ADCQ_SR, &stat);
|
||||
|
||||
if (stat & (MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR))
|
||||
mx25_tcq_re_enable_touch_detection(priv);
|
||||
|
||||
if (stat & MX25_ADCQ_SR_PD) {
|
||||
mx25_tcq_disable_touch_irq(priv);
|
||||
mx25_tcq_force_queue_start(priv);
|
||||
mx25_tcq_enable_fifo_irq(priv);
|
||||
}
|
||||
|
||||
if (stat & MX25_ADCQ_SR_FDRY) {
|
||||
mx25_tcq_disable_fifo_irq(priv);
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
|
||||
MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
|
||||
MX25_ADCQ_SR_PD,
|
||||
MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR |
|
||||
MX25_ADCQ_SR_FOR | MX25_ADCQ_SR_PD);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* configure the state machine for a 4-wire touchscreen */
|
||||
static int mx25_tcq_init(struct mx25_tcq_priv *priv)
|
||||
{
|
||||
u32 tgcr;
|
||||
unsigned int ipg_div;
|
||||
unsigned int adc_period;
|
||||
unsigned int debounce_cnt;
|
||||
unsigned int settling_cnt;
|
||||
int itemct;
|
||||
int error;
|
||||
|
||||
regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr);
|
||||
ipg_div = max_t(unsigned int, 4, MX25_TGCR_GET_ADCCLK(tgcr));
|
||||
adc_period = USEC_PER_SEC * ipg_div * 2 + 2;
|
||||
adc_period /= clk_get_rate(priv->clk) / 1000 + 1;
|
||||
debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1;
|
||||
settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1;
|
||||
|
||||
/* Reset */
|
||||
regmap_write(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST);
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST, 0);
|
||||
|
||||
/* up to 128 * 8 ADC clocks are possible */
|
||||
if (debounce_cnt > 127)
|
||||
debounce_cnt = 127;
|
||||
|
||||
/* up to 255 * 8 ADC clocks are possible */
|
||||
if (settling_cnt > 255)
|
||||
settling_cnt = 255;
|
||||
|
||||
error = imx25_setup_queue_4wire(priv, settling_cnt, &itemct);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_LITEMID_MASK | MX25_ADCQ_CR_WMRK_MASK,
|
||||
MX25_ADCQ_CR_LITEMID(itemct - 1) |
|
||||
MX25_ADCQ_CR_WMRK(priv->expected_samples - 1));
|
||||
|
||||
/* setup debounce count */
|
||||
regmap_update_bits(priv->core_regs, MX25_TSC_TGCR,
|
||||
MX25_TGCR_PDBTIME_MASK,
|
||||
MX25_TGCR_PDBTIME(debounce_cnt));
|
||||
|
||||
/* enable debounce */
|
||||
regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN,
|
||||
MX25_TGCR_PDBEN);
|
||||
regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN,
|
||||
MX25_TGCR_PDEN);
|
||||
|
||||
/* enable the engine on demand */
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK,
|
||||
MX25_ADCQ_CR_QSM_FQS);
|
||||
|
||||
/* Enable repeat and repeat wait */
|
||||
regmap_update_bits(priv->regs, MX25_ADCQ_CR,
|
||||
MX25_ADCQ_CR_RPT | MX25_ADCQ_CR_RWAIT_MASK,
|
||||
MX25_ADCQ_CR_RPT |
|
||||
MX25_ADCQ_CR_RWAIT(MX25_TSC_REPEAT_WAIT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mx25_tcq_parse_dt(struct platform_device *pdev,
|
||||
struct mx25_tcq_priv *priv)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
u32 wires;
|
||||
int error;
|
||||
|
||||
/* Setup defaults */
|
||||
priv->pen_threshold = 500;
|
||||
priv->sample_count = 3;
|
||||
priv->pen_debounce = 1000000;
|
||||
priv->settling_time = 250000;
|
||||
|
||||
error = of_property_read_u32(np, "fsl,wires", &wires);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Failed to find fsl,wires properties\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
if (wires == 4) {
|
||||
priv->mode = MX25_TS_4WIRE;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "%u-wire mode not supported\n", wires);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* These are optional, we don't care about the return values */
|
||||
of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold);
|
||||
of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time);
|
||||
of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mx25_tcq_open(struct input_dev *idev)
|
||||
{
|
||||
struct device *dev = &idev->dev;
|
||||
struct mx25_tcq_priv *priv = dev_get_drvdata(dev);
|
||||
int error;
|
||||
|
||||
error = clk_prepare_enable(priv->clk);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to enable ipg clock\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = mx25_tcq_init(priv);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to init tcq\n");
|
||||
clk_disable_unprepare(priv->clk);
|
||||
return error;
|
||||
}
|
||||
|
||||
mx25_tcq_re_enable_touch_detection(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mx25_tcq_close(struct input_dev *idev)
|
||||
{
|
||||
struct mx25_tcq_priv *priv = input_get_drvdata(idev);
|
||||
|
||||
mx25_tcq_force_queue_stop(priv);
|
||||
mx25_tcq_disable_touch_irq(priv);
|
||||
mx25_tcq_disable_fifo_irq(priv);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
}
|
||||
|
||||
static int mx25_tcq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct input_dev *idev;
|
||||
struct mx25_tcq_priv *priv;
|
||||
struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
|
||||
struct resource *res;
|
||||
void __iomem *mem;
|
||||
int error;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
priv->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mem = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(mem))
|
||||
return PTR_ERR(mem);
|
||||
|
||||
error = mx25_tcq_parse_dt(pdev, priv);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig);
|
||||
if (IS_ERR(priv->regs)) {
|
||||
dev_err(dev, "Failed to initialize regmap\n");
|
||||
return PTR_ERR(priv->regs);
|
||||
}
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq <= 0) {
|
||||
dev_err(dev, "Failed to get IRQ\n");
|
||||
return priv->irq;
|
||||
}
|
||||
|
||||
idev = devm_input_allocate_device(dev);
|
||||
if (!idev) {
|
||||
dev_err(dev, "Failed to allocate input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
idev->name = mx25_tcq_name;
|
||||
input_set_capability(idev, EV_KEY, BTN_TOUCH);
|
||||
input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
|
||||
input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
|
||||
|
||||
idev->id.bustype = BUS_HOST;
|
||||
idev->open = mx25_tcq_open;
|
||||
idev->close = mx25_tcq_close;
|
||||
|
||||
priv->idev = idev;
|
||||
input_set_drvdata(idev, priv);
|
||||
|
||||
priv->core_regs = tsadc->regs;
|
||||
if (!priv->core_regs)
|
||||
return -EINVAL;
|
||||
|
||||
priv->clk = tsadc->clk;
|
||||
if (!priv->clk)
|
||||
return -EINVAL;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq,
|
||||
mx25_tcq_irq_thread, 0, pdev->name,
|
||||
priv);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed requesting IRQ\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(idev);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to register input device\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mx25_tcq_driver = {
|
||||
.driver = {
|
||||
.name = "mx25-tcq",
|
||||
.of_match_table = mx25_tcq_ids,
|
||||
},
|
||||
.probe = mx25_tcq_probe,
|
||||
};
|
||||
module_platform_driver(mx25_tcq_driver);
|
||||
|
||||
MODULE_DESCRIPTION("TS input driver for Freescale mx25");
|
||||
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -18,6 +18,17 @@ config MFD_CS5535
|
||||
This is the core driver for CS5535/CS5536 MFD functions. This is
|
||||
necessary for using the board's GPIO and MFGPT functionality.
|
||||
|
||||
config MFD_ACT8945A
|
||||
tristate "Active-semi ACT8945A"
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
depends on I2C && OF
|
||||
help
|
||||
Support for the ACT8945A PMIC from Active-semi. This device
|
||||
features three step-down DC/DC converters and four low-dropout
|
||||
linear regulators, along with a complete ActivePath battery
|
||||
charger.
|
||||
|
||||
config MFD_AS3711
|
||||
bool "AMS AS3711"
|
||||
select MFD_CORE
|
||||
@ -91,14 +102,29 @@ config MFD_BCM590XX
|
||||
Support for the BCM590xx PMUs from Broadcom
|
||||
|
||||
config MFD_AXP20X
|
||||
bool "X-Powers AXP20X"
|
||||
tristate
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
depends on I2C=y
|
||||
|
||||
config MFD_AXP20X_I2C
|
||||
tristate "X-Powers AXP series PMICs with I2C"
|
||||
select MFD_AXP20X
|
||||
select REGMAP_I2C
|
||||
depends on I2C
|
||||
help
|
||||
If you say Y here you get support for the X-Powers AXP202, AXP209 and
|
||||
AXP288 power management IC (PMIC).
|
||||
If you say Y here you get support for the X-Powers AXP series power
|
||||
management ICs (PMICs) controlled with I2C.
|
||||
This driver include only the core APIs. You have to select individual
|
||||
components like regulators or the PEK (Power Enable Key) under the
|
||||
corresponding menus.
|
||||
|
||||
config MFD_AXP20X_RSB
|
||||
tristate "X-Powers AXP series PMICs with RSB"
|
||||
select MFD_AXP20X
|
||||
depends on SUNXI_RSB
|
||||
help
|
||||
If you say Y here you get support for the X-Powers AXP series power
|
||||
management ICs (PMICs) controlled with RSB.
|
||||
This driver include only the core APIs. You have to select individual
|
||||
components like regulators or the PEK (Power Enable Key) under the
|
||||
corresponding menus.
|
||||
@ -203,7 +229,7 @@ config MFD_DA9062
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
help
|
||||
Say yes here for support for the Dialog Semiconductor DA9062 PMIC.
|
||||
This includes the I2C driver and core APIs.
|
||||
@ -215,7 +241,7 @@ config MFD_DA9063
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
help
|
||||
Say yes here for support for the Dialog Semiconductor DA9063 PMIC.
|
||||
This includes the I2C driver and core APIs.
|
||||
@ -224,7 +250,7 @@ config MFD_DA9063
|
||||
|
||||
config MFD_DA9150
|
||||
tristate "Dialog Semiconductor DA9150 Charger Fuel-Gauge chip"
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
@ -271,6 +297,15 @@ config MFD_MC13XXX_I2C
|
||||
help
|
||||
Select this if your MC13xxx is connected via an I2C bus.
|
||||
|
||||
config MFD_MX25_TSADC
|
||||
tristate "Freescale i.MX25 integrated Touchscreen and ADC unit"
|
||||
select REGMAP_MMIO
|
||||
depends on (SOC_IMX25 && OF) || COMPILE_TEST
|
||||
help
|
||||
Enable support for the integrated Touchscreen and ADC unit of the
|
||||
i.MX25 processors. They consist of a conversion queue for general
|
||||
purpose ADC and a queue for Touchscreens.
|
||||
|
||||
config MFD_HI6421_PMIC
|
||||
tristate "HiSilicon Hi6421 PMU/Codec IC"
|
||||
depends on OF
|
||||
@ -445,7 +480,7 @@ config MFD_KEMPLD
|
||||
|
||||
config MFD_88PM800
|
||||
tristate "Marvell 88PM800"
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select MFD_CORE
|
||||
@ -457,7 +492,7 @@ config MFD_88PM800
|
||||
|
||||
config MFD_88PM805
|
||||
tristate "Marvell 88PM805"
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select MFD_CORE
|
||||
@ -493,8 +528,8 @@ config MFD_MAX14577
|
||||
of the device.
|
||||
|
||||
config MFD_MAX77686
|
||||
bool "Maxim Semiconductor MAX77686/802 PMIC Support"
|
||||
depends on I2C=y
|
||||
tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
@ -538,7 +573,7 @@ config MFD_MAX77843
|
||||
config MFD_MAX8907
|
||||
tristate "Maxim Semiconductor MAX8907 PMIC Support"
|
||||
select MFD_CORE
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
@ -743,7 +778,7 @@ config MFD_RTSX_PCI
|
||||
|
||||
config MFD_RT5033
|
||||
tristate "Richtek RT5033 Power Management IC"
|
||||
depends on I2C=y
|
||||
depends on I2C
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
@ -1106,6 +1141,19 @@ config TPS6507X
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tps6507x.
|
||||
|
||||
config MFD_TPS65086
|
||||
tristate "TI TPS65086 Power Management Integrated Chips (PMICs)"
|
||||
select REGMAP
|
||||
select REGMAP_IRQ
|
||||
select REGMAP_I2C
|
||||
depends on I2C
|
||||
help
|
||||
If you say yes here you get support for the TPS65086 series of
|
||||
Power Management chips.
|
||||
This driver provides common support for accessing the device,
|
||||
additional drivers must be enabled in order to use the
|
||||
functionality of the device.
|
||||
|
||||
config TPS65911_COMPARATOR
|
||||
tristate
|
||||
|
||||
@ -1370,7 +1418,6 @@ config MFD_ARIZONA
|
||||
config MFD_ARIZONA_I2C
|
||||
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C"
|
||||
select MFD_ARIZONA
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
depends on I2C
|
||||
help
|
||||
@ -1380,12 +1427,11 @@ config MFD_ARIZONA_I2C
|
||||
config MFD_ARIZONA_SPI
|
||||
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with SPI"
|
||||
select MFD_ARIZONA
|
||||
select MFD_CORE
|
||||
select REGMAP_SPI
|
||||
depends on SPI_MASTER
|
||||
help
|
||||
Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
|
||||
audio SoC core functionality controlled via I2C.
|
||||
audio SoC core functionality controlled via SPI.
|
||||
|
||||
config MFD_CS47L24
|
||||
bool "Cirrus Logic CS47L24 and WM1831"
|
||||
|
@ -6,6 +6,7 @@
|
||||
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
|
||||
obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
|
||||
obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
|
||||
obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
|
||||
obj-$(CONFIG_MFD_SM501) += sm501.o
|
||||
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
|
||||
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
|
||||
@ -70,6 +71,7 @@ obj-$(CONFIG_MFD_WM8994) += wm8994.o
|
||||
obj-$(CONFIG_TPS6105X) += tps6105x.o
|
||||
obj-$(CONFIG_TPS65010) += tps65010.o
|
||||
obj-$(CONFIG_TPS6507X) += tps6507x.o
|
||||
obj-$(CONFIG_MFD_TPS65086) += tps65086.o
|
||||
obj-$(CONFIG_MFD_TPS65217) += tps65217.o
|
||||
obj-$(CONFIG_MFD_TPS65218) += tps65218.o
|
||||
obj-$(CONFIG_MFD_TPS65910) += tps65910.o
|
||||
@ -84,6 +86,8 @@ obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
|
||||
obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
|
||||
obj-$(CONFIG_TWL6040_CORE) += twl6040.o
|
||||
|
||||
obj-$(CONFIG_MFD_MX25_TSADC) += fsl-imx25-tsadc.o
|
||||
|
||||
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
|
||||
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
|
||||
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
|
||||
@ -110,6 +114,8 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
|
||||
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
|
||||
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
|
||||
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
|
||||
obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
|
||||
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
|
||||
|
||||
obj-$(CONFIG_MFD_LP3943) += lp3943.o
|
||||
obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
|
||||
|
102
drivers/mfd/act8945a.c
Normal file
102
drivers/mfd/act8945a.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* MFD driver for Active-semi ACT8945a PMIC
|
||||
*
|
||||
* Copyright (C) 2015 Atmel Corporation.
|
||||
*
|
||||
* Author: Wenyou Yang <wenyou.yang@atmel.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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell act8945a_devs[] = {
|
||||
{
|
||||
.name = "act8945a-regulator",
|
||||
},
|
||||
{
|
||||
.name = "act8945a-charger",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_config act8945a_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int act8945a_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &act8945a_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c, regmap);
|
||||
|
||||
ret = mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE, act8945a_devs,
|
||||
ARRAY_SIZE(act8945a_devs), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to add sub devices\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int act8945a_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id act8945a_i2c_id[] = {
|
||||
{ "act8945a", 0 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, act8945a_i2c_id);
|
||||
|
||||
static const struct of_device_id act8945a_of_match[] = {
|
||||
{ .compatible = "active-semi,act8945a", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, act8945a_of_match);
|
||||
|
||||
static struct i2c_driver act8945a_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "act8945a",
|
||||
.of_match_table = of_match_ptr(act8945a_of_match),
|
||||
},
|
||||
.probe = act8945a_i2c_probe,
|
||||
.remove = act8945a_i2c_remove,
|
||||
.id_table = act8945a_i2c_id,
|
||||
};
|
||||
|
||||
static int __init act8945a_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&act8945a_i2c_driver);
|
||||
}
|
||||
subsys_initcall(act8945a_i2c_init);
|
||||
|
||||
static void __exit act8945a_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&act8945a_i2c_driver);
|
||||
}
|
||||
module_exit(act8945a_i2c_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ACT8945A PMIC multi-function driver");
|
||||
MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -108,8 +108,8 @@ static const struct regmap_config as3711_regmap_config = {
|
||||
.volatile_reg = as3711_volatile_reg,
|
||||
.readable_reg = as3711_readable_reg,
|
||||
.precious_reg = as3711_precious_reg,
|
||||
.max_register = AS3711_MAX_REGS,
|
||||
.num_reg_defaults_raw = AS3711_MAX_REGS,
|
||||
.max_register = AS3711_MAX_REG,
|
||||
.num_reg_defaults_raw = AS3711_NUM_REGS,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
|
104
drivers/mfd/axp20x-i2c.c
Normal file
104
drivers/mfd/axp20x-i2c.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* I2C driver for the X-Powers' Power Management ICs
|
||||
*
|
||||
* AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
|
||||
* converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
|
||||
* as well as configurable GPIOs.
|
||||
*
|
||||
* This driver supports the I2C variants.
|
||||
*
|
||||
* Copyright (C) 2014 Carlo Caione
|
||||
*
|
||||
* Author: Carlo Caione <carlo@caione.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/axp20x.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static int axp20x_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct axp20x_dev *axp20x;
|
||||
int ret;
|
||||
|
||||
axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
|
||||
if (!axp20x)
|
||||
return -ENOMEM;
|
||||
|
||||
axp20x->dev = &i2c->dev;
|
||||
axp20x->irq = i2c->irq;
|
||||
dev_set_drvdata(axp20x->dev, axp20x);
|
||||
|
||||
ret = axp20x_match_device(axp20x);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg);
|
||||
if (IS_ERR(axp20x->regmap)) {
|
||||
ret = PTR_ERR(axp20x->regmap);
|
||||
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return axp20x_device_probe(axp20x);
|
||||
}
|
||||
|
||||
static int axp20x_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
|
||||
|
||||
return axp20x_device_remove(axp20x);
|
||||
}
|
||||
|
||||
static const struct of_device_id axp20x_i2c_of_match[] = {
|
||||
{ .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
|
||||
{ .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
|
||||
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
|
||||
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
|
||||
|
||||
/*
|
||||
* This is useless for OF-enabled devices, but it is needed by I2C subsystem
|
||||
*/
|
||||
static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
|
||||
|
||||
static const struct acpi_device_id axp20x_i2c_acpi_match[] = {
|
||||
{
|
||||
.id = "INT33F4",
|
||||
.driver_data = AXP288_ID,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, axp20x_i2c_acpi_match);
|
||||
|
||||
static struct i2c_driver axp20x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "axp20x-i2c",
|
||||
.of_match_table = of_match_ptr(axp20x_i2c_of_match),
|
||||
.acpi_match_table = ACPI_PTR(axp20x_i2c_acpi_match),
|
||||
},
|
||||
.probe = axp20x_i2c_probe,
|
||||
.remove = axp20x_i2c_remove,
|
||||
.id_table = axp20x_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(axp20x_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("PMIC MFD I2C driver for AXP20X");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
MODULE_LICENSE("GPL");
|
80
drivers/mfd/axp20x-rsb.c
Normal file
80
drivers/mfd/axp20x-rsb.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* RSB driver for the X-Powers' Power Management ICs
|
||||
*
|
||||
* AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
|
||||
* converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
|
||||
* as well as configurable GPIOs.
|
||||
*
|
||||
* This driver supports the RSB variants.
|
||||
*
|
||||
* Copyright (C) 2015 Chen-Yu Tsai
|
||||
*
|
||||
* Author: Chen-Yu Tsai <wens@csie.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mfd/axp20x.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sunxi-rsb.h>
|
||||
|
||||
static int axp20x_rsb_probe(struct sunxi_rsb_device *rdev)
|
||||
{
|
||||
struct axp20x_dev *axp20x;
|
||||
int ret;
|
||||
|
||||
axp20x = devm_kzalloc(&rdev->dev, sizeof(*axp20x), GFP_KERNEL);
|
||||
if (!axp20x)
|
||||
return -ENOMEM;
|
||||
|
||||
axp20x->dev = &rdev->dev;
|
||||
axp20x->irq = rdev->irq;
|
||||
dev_set_drvdata(&rdev->dev, axp20x);
|
||||
|
||||
ret = axp20x_match_device(axp20x);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
axp20x->regmap = devm_regmap_init_sunxi_rsb(rdev, axp20x->regmap_cfg);
|
||||
if (IS_ERR(axp20x->regmap)) {
|
||||
ret = PTR_ERR(axp20x->regmap);
|
||||
dev_err(&rdev->dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return axp20x_device_probe(axp20x);
|
||||
}
|
||||
|
||||
static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
|
||||
{
|
||||
struct axp20x_dev *axp20x = sunxi_rsb_device_get_drvdata(rdev);
|
||||
|
||||
return axp20x_device_remove(axp20x);
|
||||
}
|
||||
|
||||
static const struct of_device_id axp20x_rsb_of_match[] = {
|
||||
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_rsb_of_match);
|
||||
|
||||
static struct sunxi_rsb_driver axp20x_rsb_driver = {
|
||||
.driver = {
|
||||
.name = "axp20x-rsb",
|
||||
.of_match_table = of_match_ptr(axp20x_rsb_of_match),
|
||||
},
|
||||
.probe = axp20x_rsb_probe,
|
||||
.remove = axp20x_rsb_remove,
|
||||
};
|
||||
module_sunxi_rsb_driver(axp20x_rsb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("PMIC MFD sunXi RSB driver for AXP20X");
|
||||
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1,10 +1,14 @@
|
||||
/*
|
||||
* axp20x.c - MFD core driver for the X-Powers' Power Management ICs
|
||||
* MFD core driver for the X-Powers' Power Management ICs
|
||||
*
|
||||
* AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
|
||||
* converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
|
||||
* as well as configurable GPIOs.
|
||||
*
|
||||
* This file contains the interface independent core functions.
|
||||
*
|
||||
* Copyright (C) 2014 Carlo Caione
|
||||
*
|
||||
* Author: Carlo Caione <carlo@caione.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -13,18 +17,15 @@
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mfd/axp20x.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#define AXP20X_OFF 0x80
|
||||
@ -34,6 +35,7 @@ static const char * const axp20x_model_names[] = {
|
||||
"AXP202",
|
||||
"AXP209",
|
||||
"AXP221",
|
||||
"AXP223",
|
||||
"AXP288",
|
||||
};
|
||||
|
||||
@ -376,32 +378,6 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
|
||||
};
|
||||
|
||||
static const struct of_device_id axp20x_of_match[] = {
|
||||
{ .compatible = "x-powers,axp152", .data = (void *) AXP152_ID },
|
||||
{ .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
|
||||
{ .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
|
||||
{ .compatible = "x-powers,axp221", .data = (void *) AXP221_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_of_match);
|
||||
|
||||
/*
|
||||
* This is useless for OF-enabled devices, but it is needed by I2C subsystem
|
||||
*/
|
||||
static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
|
||||
|
||||
static const struct acpi_device_id axp20x_acpi_match[] = {
|
||||
{
|
||||
.id = "INT33F4",
|
||||
.driver_data = AXP288_ID,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, axp20x_acpi_match);
|
||||
|
||||
static const struct regmap_irq_chip axp152_regmap_irq_chip = {
|
||||
.name = "axp152_irq_chip",
|
||||
.status_base = AXP152_IRQ1_STATE,
|
||||
@ -606,25 +582,26 @@ static void axp20x_power_off(void)
|
||||
AXP20X_OFF);
|
||||
}
|
||||
|
||||
static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
|
||||
int axp20x_match_device(struct axp20x_dev *axp20x)
|
||||
{
|
||||
struct device *dev = axp20x->dev;
|
||||
const struct acpi_device_id *acpi_id;
|
||||
const struct of_device_id *of_id;
|
||||
|
||||
if (dev->of_node) {
|
||||
of_id = of_match_device(axp20x_of_match, dev);
|
||||
of_id = of_match_device(dev->driver->of_match_table, dev);
|
||||
if (!of_id) {
|
||||
dev_err(dev, "Unable to match OF ID\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
axp20x->variant = (long) of_id->data;
|
||||
axp20x->variant = (long)of_id->data;
|
||||
} else {
|
||||
acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
if (!acpi_id || !acpi_id->driver_data) {
|
||||
dev_err(dev, "Unable to match ACPI ID and data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
axp20x->variant = (long) acpi_id->driver_data;
|
||||
axp20x->variant = (long)acpi_id->driver_data;
|
||||
}
|
||||
|
||||
switch (axp20x->variant) {
|
||||
@ -642,6 +619,7 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
|
||||
axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
|
||||
break;
|
||||
case AXP221_ID:
|
||||
case AXP223_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
|
||||
axp20x->cells = axp22x_cells;
|
||||
axp20x->regmap_cfg = &axp22x_regmap_config;
|
||||
@ -658,51 +636,31 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(dev, "AXP20x variant %s found\n",
|
||||
axp20x_model_names[axp20x->variant]);
|
||||
axp20x_model_names[axp20x->variant]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(axp20x_match_device);
|
||||
|
||||
static int axp20x_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
int axp20x_device_probe(struct axp20x_dev *axp20x)
|
||||
{
|
||||
struct axp20x_dev *axp20x;
|
||||
int ret;
|
||||
|
||||
axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
|
||||
if (!axp20x)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = axp20x_match_device(axp20x, &i2c->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
axp20x->i2c_client = i2c;
|
||||
axp20x->dev = &i2c->dev;
|
||||
dev_set_drvdata(axp20x->dev, axp20x);
|
||||
|
||||
axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg);
|
||||
if (IS_ERR(axp20x->regmap)) {
|
||||
ret = PTR_ERR(axp20x->regmap);
|
||||
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq,
|
||||
ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, -1,
|
||||
axp20x->regmap_irq_chip,
|
||||
&axp20x->regmap_irqc);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret);
|
||||
dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
|
||||
axp20x->nr_cells, NULL, 0, NULL);
|
||||
axp20x->nr_cells, NULL, 0, NULL);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
|
||||
regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc);
|
||||
dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
|
||||
regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -711,38 +669,25 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
|
||||
pm_power_off = axp20x_power_off;
|
||||
}
|
||||
|
||||
dev_info(&i2c->dev, "AXP20X driver loaded\n");
|
||||
dev_info(axp20x->dev, "AXP20X driver loaded\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(axp20x_device_probe);
|
||||
|
||||
static int axp20x_i2c_remove(struct i2c_client *i2c)
|
||||
int axp20x_device_remove(struct axp20x_dev *axp20x)
|
||||
{
|
||||
struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
|
||||
|
||||
if (axp20x == axp20x_pm_power_off) {
|
||||
axp20x_pm_power_off = NULL;
|
||||
pm_power_off = NULL;
|
||||
}
|
||||
|
||||
mfd_remove_devices(axp20x->dev);
|
||||
regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc);
|
||||
regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver axp20x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "axp20x",
|
||||
.of_match_table = of_match_ptr(axp20x_of_match),
|
||||
.acpi_match_table = ACPI_PTR(axp20x_acpi_match),
|
||||
},
|
||||
.probe = axp20x_i2c_probe,
|
||||
.remove = axp20x_i2c_remove,
|
||||
.id_table = axp20x_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(axp20x_i2c_driver);
|
||||
EXPORT_SYMBOL(axp20x_device_remove);
|
||||
|
||||
MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
|
@ -227,8 +227,6 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
|
||||
{ 0x00000175, 0x0006 }, /* R373 - FLL1 Control 5 */
|
||||
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
|
||||
{ 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */
|
||||
{ 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
|
||||
{ 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */
|
||||
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
|
||||
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
|
||||
@ -245,8 +243,6 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
|
||||
{ 0x00000195, 0x000C }, /* R405 - FLL2 Control 5 */
|
||||
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
|
||||
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
|
||||
{ 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
|
||||
{ 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */
|
||||
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
|
||||
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
|
||||
@ -678,7 +674,7 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */
|
||||
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
|
||||
{ 0x00000C20, 0x0002 }, /* R3104 - Misc Pad Ctrl 1 */
|
||||
{ 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C21, 0x0000 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
|
||||
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
|
||||
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
|
||||
@ -858,8 +854,6 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL1_CONTROL_5:
|
||||
case ARIZONA_FLL1_CONTROL_6:
|
||||
case ARIZONA_FLL1_CONTROL_7:
|
||||
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_3:
|
||||
@ -876,8 +870,6 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL2_CONTROL_5:
|
||||
case ARIZONA_FLL2_CONTROL_6:
|
||||
case ARIZONA_FLL2_CONTROL_7:
|
||||
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_3:
|
||||
|
@ -388,11 +388,32 @@ static const struct regmap_range da9062_aa_volatile_ranges[] = {
|
||||
.range_min = DA9062AA_STATUS_D,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_F,
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_CONTROL_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_E,
|
||||
.range_max = DA9062AA_CONTROL_F,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK2_CONT,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_COUNT_S,
|
||||
.range_max = DA9062AA_SECOND_D,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_SEQ,
|
||||
}, {
|
||||
.range_min = DA9062AA_EN_32K,
|
||||
.range_max = DA9062AA_EN_32K,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -74,17 +74,29 @@ static const struct regmap_range da9063_ad_writeable_ranges[] = {
|
||||
|
||||
static const struct regmap_range da9063_ad_volatile_ranges[] = {
|
||||
{
|
||||
.range_min = DA9063_REG_STATUS_A,
|
||||
.range_min = DA9063_REG_PAGE_CON,
|
||||
.range_max = DA9063_REG_EVENT_D,
|
||||
}, {
|
||||
.range_min = DA9063_REG_CONTROL_F,
|
||||
.range_min = DA9063_REG_CONTROL_A,
|
||||
.range_max = DA9063_REG_CONTROL_B,
|
||||
}, {
|
||||
.range_min = DA9063_REG_CONTROL_E,
|
||||
.range_max = DA9063_REG_CONTROL_F,
|
||||
}, {
|
||||
.range_min = DA9063_REG_ADC_MAN,
|
||||
.range_min = DA9063_REG_BCORE2_CONT,
|
||||
.range_max = DA9063_REG_LDO11_CONT,
|
||||
}, {
|
||||
.range_min = DA9063_REG_DVC_1,
|
||||
.range_max = DA9063_REG_ADC_MAN,
|
||||
}, {
|
||||
.range_min = DA9063_REG_ADC_RES_L,
|
||||
.range_max = DA9063_AD_REG_SECOND_D,
|
||||
}, {
|
||||
.range_min = DA9063_REG_SEQ,
|
||||
.range_max = DA9063_REG_SEQ,
|
||||
}, {
|
||||
.range_min = DA9063_REG_EN_32K,
|
||||
.range_max = DA9063_REG_EN_32K,
|
||||
}, {
|
||||
.range_min = DA9063_AD_REG_MON_REG_5,
|
||||
.range_max = DA9063_AD_REG_MON_REG_6,
|
||||
@ -152,17 +164,29 @@ static const struct regmap_range da9063_bb_writeable_ranges[] = {
|
||||
|
||||
static const struct regmap_range da9063_bb_volatile_ranges[] = {
|
||||
{
|
||||
.range_min = DA9063_REG_STATUS_A,
|
||||
.range_min = DA9063_REG_PAGE_CON,
|
||||
.range_max = DA9063_REG_EVENT_D,
|
||||
}, {
|
||||
.range_min = DA9063_REG_CONTROL_F,
|
||||
.range_min = DA9063_REG_CONTROL_A,
|
||||
.range_max = DA9063_REG_CONTROL_B,
|
||||
}, {
|
||||
.range_min = DA9063_REG_CONTROL_E,
|
||||
.range_max = DA9063_REG_CONTROL_F,
|
||||
}, {
|
||||
.range_min = DA9063_REG_ADC_MAN,
|
||||
.range_min = DA9063_REG_BCORE2_CONT,
|
||||
.range_max = DA9063_REG_LDO11_CONT,
|
||||
}, {
|
||||
.range_min = DA9063_REG_DVC_1,
|
||||
.range_max = DA9063_REG_ADC_MAN,
|
||||
}, {
|
||||
.range_min = DA9063_REG_ADC_RES_L,
|
||||
.range_max = DA9063_BB_REG_SECOND_D,
|
||||
}, {
|
||||
.range_min = DA9063_REG_SEQ,
|
||||
.range_max = DA9063_REG_SEQ,
|
||||
}, {
|
||||
.range_min = DA9063_REG_EN_32K,
|
||||
.range_max = DA9063_REG_EN_32K,
|
||||
}, {
|
||||
.range_min = DA9063_BB_REG_MON_REG_5,
|
||||
.range_max = DA9063_BB_REG_MON_REG_6,
|
||||
|
@ -739,20 +739,17 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
|
||||
if (!div && !requests[clkout])
|
||||
return -EINVAL;
|
||||
|
||||
switch (clkout) {
|
||||
case 0:
|
||||
if (clkout == 0) {
|
||||
div_mask = PRCM_CLKOCR_CLKODIV0_MASK;
|
||||
mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK);
|
||||
bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) |
|
||||
(div << PRCM_CLKOCR_CLKODIV0_SHIFT));
|
||||
break;
|
||||
case 1:
|
||||
} else {
|
||||
div_mask = PRCM_CLKOCR_CLKODIV1_MASK;
|
||||
mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK |
|
||||
PRCM_CLKOCR_CLK1TYPE);
|
||||
bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) |
|
||||
(div << PRCM_CLKOCR_CLKODIV1_SHIFT));
|
||||
break;
|
||||
}
|
||||
bits &= mask;
|
||||
|
||||
|
203
drivers/mfd/fsl-imx25-tsadc.c
Normal file
203
drivers/mfd/fsl-imx25-tsadc.c
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/irqdesc.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/imx25-tsadc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static struct regmap_config mx25_tsadc_regmap_config = {
|
||||
.fast_io = true,
|
||||
.max_register = 8,
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static void mx25_tsadc_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct mx25_tsadc *tsadc = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
u32 status;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
regmap_read(tsadc->regs, MX25_TSC_TGSR, &status);
|
||||
|
||||
if (status & MX25_TGSR_GCQ_INT)
|
||||
generic_handle_irq(irq_find_mapping(tsadc->domain, 1));
|
||||
|
||||
if (status & MX25_TGSR_TCQ_INT)
|
||||
generic_handle_irq(irq_find_mapping(tsadc->domain, 0));
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
static int mx25_tsadc_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
struct mx25_tsadc *tsadc = d->host_data;
|
||||
|
||||
irq_set_chip_data(irq, tsadc);
|
||||
irq_set_chip_and_handler(irq, &dummy_irq_chip,
|
||||
handle_level_irq);
|
||||
irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_domain_ops mx25_tsadc_domain_ops = {
|
||||
.map = mx25_tsadc_domain_map,
|
||||
.xlate = irq_domain_xlate_onecell,
|
||||
};
|
||||
|
||||
static int mx25_tsadc_setup_irq(struct platform_device *pdev,
|
||||
struct mx25_tsadc *tsadc)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0) {
|
||||
dev_err(dev, "Failed to get irq\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
|
||||
tsadc);
|
||||
if (!tsadc->domain) {
|
||||
dev_err(dev, "Failed to add irq domain\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
irq_set_chained_handler(irq, mx25_tsadc_irq_handler);
|
||||
irq_set_handler_data(irq, tsadc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mx25_tsadc_setup_clk(struct platform_device *pdev,
|
||||
struct mx25_tsadc *tsadc)
|
||||
{
|
||||
unsigned clk_div;
|
||||
|
||||
/*
|
||||
* According to the datasheet the ADC clock should never
|
||||
* exceed 1,75 MHz. Base clock is the IPG and the ADC unit uses
|
||||
* a funny clock divider. To keep the ADC conversion time constant
|
||||
* adapt the ADC internal clock divider to the IPG clock rate.
|
||||
*/
|
||||
|
||||
dev_dbg(&pdev->dev, "Found master clock at %lu Hz\n",
|
||||
clk_get_rate(tsadc->clk));
|
||||
|
||||
clk_div = DIV_ROUND_UP(clk_get_rate(tsadc->clk), 1750000);
|
||||
dev_dbg(&pdev->dev, "Setting up ADC clock divider to %u\n", clk_div);
|
||||
|
||||
/* adc clock = IPG clock / (2 * div + 2) */
|
||||
clk_div -= 2;
|
||||
clk_div /= 2;
|
||||
|
||||
/*
|
||||
* the ADC clock divider changes its behaviour when values below 4
|
||||
* are used: it is fixed to "/ 10" in this case
|
||||
*/
|
||||
clk_div = max_t(unsigned, 4, clk_div);
|
||||
|
||||
dev_dbg(&pdev->dev, "Resulting ADC conversion clock at %lu Hz\n",
|
||||
clk_get_rate(tsadc->clk) / (2 * clk_div + 2));
|
||||
|
||||
regmap_update_bits(tsadc->regs, MX25_TSC_TGCR,
|
||||
MX25_TGCR_ADCCLKCFG(0x1f),
|
||||
MX25_TGCR_ADCCLKCFG(clk_div));
|
||||
}
|
||||
|
||||
static int mx25_tsadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct mx25_tsadc *tsadc;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
void __iomem *iomem;
|
||||
|
||||
tsadc = devm_kzalloc(dev, sizeof(*tsadc), GFP_KERNEL);
|
||||
if (!tsadc)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
iomem = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(iomem))
|
||||
return PTR_ERR(iomem);
|
||||
|
||||
tsadc->regs = devm_regmap_init_mmio(dev, iomem,
|
||||
&mx25_tsadc_regmap_config);
|
||||
if (IS_ERR(tsadc->regs)) {
|
||||
dev_err(dev, "Failed to initialize regmap\n");
|
||||
return PTR_ERR(tsadc->regs);
|
||||
}
|
||||
|
||||
tsadc->clk = devm_clk_get(dev, "ipg");
|
||||
if (IS_ERR(tsadc->clk)) {
|
||||
dev_err(dev, "Failed to get ipg clock\n");
|
||||
return PTR_ERR(tsadc->clk);
|
||||
}
|
||||
|
||||
/* setup clock according to the datasheet */
|
||||
mx25_tsadc_setup_clk(pdev, tsadc);
|
||||
|
||||
/* Enable clock and reset the component */
|
||||
regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_CLK_EN,
|
||||
MX25_TGCR_CLK_EN);
|
||||
regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_TSC_RST,
|
||||
MX25_TGCR_TSC_RST);
|
||||
|
||||
/* Setup powersaving mode, but enable internal reference voltage */
|
||||
regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_POWERMODE_MASK,
|
||||
MX25_TGCR_POWERMODE_SAVE);
|
||||
regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_INTREFEN,
|
||||
MX25_TGCR_INTREFEN);
|
||||
|
||||
ret = mx25_tsadc_setup_irq(pdev, tsadc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, tsadc);
|
||||
|
||||
of_platform_populate(np, NULL, NULL, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mx25_tsadc_ids[] = {
|
||||
{ .compatible = "fsl,imx25-tsadc" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver mx25_tsadc_driver = {
|
||||
.driver = {
|
||||
.name = "mx25-tsadc",
|
||||
.of_match_table = of_match_ptr(mx25_tsadc_ids),
|
||||
},
|
||||
.probe = mx25_tsadc_probe,
|
||||
};
|
||||
module_platform_driver(mx25_tsadc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MFD for ADC/TSC for Freescale mx25");
|
||||
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:mx25-tsadc");
|
@ -44,8 +44,20 @@ static const struct intel_lpss_platform_info bxt_info = {
|
||||
.clk_rate = 100000000,
|
||||
};
|
||||
|
||||
static struct property_entry bxt_i2c_properties[] = {
|
||||
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
|
||||
PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
|
||||
PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct property_set bxt_i2c_pset = {
|
||||
.properties = bxt_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info bxt_i2c_info = {
|
||||
.clk_rate = 133000000,
|
||||
.pset = &bxt_i2c_pset,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id intel_lpss_acpi_ids[] = {
|
||||
|
@ -107,12 +107,24 @@ static const struct intel_lpss_platform_info bxt_uart_info = {
|
||||
.pset = &uart_pset,
|
||||
};
|
||||
|
||||
static struct property_entry bxt_i2c_properties[] = {
|
||||
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
|
||||
PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
|
||||
PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct property_set bxt_i2c_pset = {
|
||||
.properties = bxt_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info bxt_i2c_info = {
|
||||
.clk_rate = 133000000,
|
||||
.pset = &bxt_i2c_pset,
|
||||
};
|
||||
|
||||
static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
/* BXT */
|
||||
/* BXT A-Step */
|
||||
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x0ab0), (kernel_ulong_t)&bxt_i2c_info },
|
||||
@ -128,6 +140,23 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info },
|
||||
/* BXT B-Step */
|
||||
{ PCI_VDEVICE(INTEL, 0x1aac), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1aae), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ab0), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ab2), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ab4), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ab6), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ab8), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1aba), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1abc), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1abe), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ac0), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ac2), (kernel_ulong_t)&bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
|
||||
|
||||
/* APL */
|
||||
{ PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info },
|
||||
|
@ -453,6 +453,7 @@ int intel_lpss_probe(struct device *dev,
|
||||
err_remove_ltr:
|
||||
intel_lpss_debugfs_remove(lpss);
|
||||
intel_lpss_ltr_hide(lpss);
|
||||
intel_lpss_unregister_clock(lpss);
|
||||
|
||||
err_clk_register:
|
||||
ida_simple_remove(&intel_lpss_devid_ida, lpss->devid);
|
||||
|
@ -52,8 +52,6 @@
|
||||
/* The Quark I2C controller source clock */
|
||||
#define INTEL_QUARK_I2C_CLK_HZ 33000000
|
||||
|
||||
#define INTEL_QUARK_I2C_NCLK 1
|
||||
|
||||
struct intel_quark_mfd {
|
||||
struct pci_dev *pdev;
|
||||
struct clk *i2c_clk;
|
||||
@ -128,30 +126,24 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
|
||||
static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
|
||||
{
|
||||
struct pci_dev *pdev = quark_mfd->pdev;
|
||||
struct clk_lookup *i2c_clk_lookup;
|
||||
struct clk *i2c_clk;
|
||||
int ret;
|
||||
|
||||
i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
|
||||
sizeof(*i2c_clk_lookup), GFP_KERNEL);
|
||||
if (!i2c_clk_lookup)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
|
||||
|
||||
i2c_clk = clk_register_fixed_rate(&pdev->dev,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
|
||||
CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
|
||||
if (IS_ERR(i2c_clk))
|
||||
return PTR_ERR(i2c_clk);
|
||||
|
||||
quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
|
||||
quark_mfd->i2c_clk = i2c_clk;
|
||||
quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK);
|
||||
|
||||
ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
|
||||
INTEL_QUARK_I2C_NCLK);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
|
||||
if (!quark_mfd->i2c_clk_lookup) {
|
||||
dev_err(&pdev->dev, "Fixed clk register failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
|
||||
|
@ -376,7 +376,7 @@ static const struct mfd_cell micro_cells[] = {
|
||||
{ .name = "ipaq-micro-leds", },
|
||||
};
|
||||
|
||||
static int micro_resume(struct device *dev)
|
||||
static int __maybe_unused micro_resume(struct device *dev)
|
||||
{
|
||||
struct ipaq_micro *micro = dev_get_drvdata(dev);
|
||||
|
||||
|
@ -169,6 +169,7 @@ static const struct of_device_id max77686_pmic_dt_match[] = {
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77686_pmic_dt_match);
|
||||
|
||||
static int max77686_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
@ -265,6 +266,7 @@ static int max77686_i2c_remove(struct i2c_client *i2c)
|
||||
|
||||
static const struct i2c_device_id max77686_i2c_id[] = {
|
||||
{ "max77686", TYPE_MAX77686 },
|
||||
{ "max77802", TYPE_MAX77802 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max77686_i2c_id);
|
||||
|
@ -19,11 +19,17 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/mt6397/core.h>
|
||||
#include <linux/mfd/mt6323/core.h>
|
||||
#include <linux/mfd/mt6397/registers.h>
|
||||
#include <linux/mfd/mt6323/registers.h>
|
||||
|
||||
#define MT6397_RTC_BASE 0xe000
|
||||
#define MT6397_RTC_SIZE 0x3e
|
||||
|
||||
#define MT6323_CID_CODE 0x23
|
||||
#define MT6391_CID_CODE 0x91
|
||||
#define MT6397_CID_CODE 0x97
|
||||
|
||||
static const struct resource mt6397_rtc_resources[] = {
|
||||
{
|
||||
.start = MT6397_RTC_BASE,
|
||||
@ -37,6 +43,13 @@ static const struct resource mt6397_rtc_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell mt6323_devs[] = {
|
||||
{
|
||||
.name = "mt6323-regulator",
|
||||
.of_compatible = "mediatek,mt6323-regulator"
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell mt6397_devs[] = {
|
||||
{
|
||||
.name = "mt6397-rtc",
|
||||
@ -69,8 +82,10 @@ static void mt6397_irq_sync_unlock(struct irq_data *data)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]);
|
||||
regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]);
|
||||
regmap_write(mt6397->regmap, mt6397->int_con[0],
|
||||
mt6397->irq_masks_cur[0]);
|
||||
regmap_write(mt6397->regmap, mt6397->int_con[1],
|
||||
mt6397->irq_masks_cur[1]);
|
||||
|
||||
mutex_unlock(&mt6397->irqlock);
|
||||
}
|
||||
@ -147,8 +162,8 @@ static irqreturn_t mt6397_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = data;
|
||||
|
||||
mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0);
|
||||
mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16);
|
||||
mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
|
||||
mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -177,8 +192,8 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
|
||||
mutex_init(&mt6397->irqlock);
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0);
|
||||
regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0);
|
||||
regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
|
||||
regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
|
||||
|
||||
mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
|
||||
MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
|
||||
@ -203,8 +218,8 @@ static int mt6397_irq_suspend(struct device *dev)
|
||||
{
|
||||
struct mt6397_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
|
||||
regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
|
||||
regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
|
||||
regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
|
||||
|
||||
enable_irq_wake(chip->irq);
|
||||
|
||||
@ -215,8 +230,8 @@ static int mt6397_irq_resume(struct device *dev)
|
||||
{
|
||||
struct mt6397_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
|
||||
regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
|
||||
regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
|
||||
regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
|
||||
|
||||
disable_irq_wake(chip->irq);
|
||||
|
||||
@ -230,34 +245,69 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
|
||||
static int mt6397_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct mt6397_chip *mt6397;
|
||||
unsigned int id;
|
||||
struct mt6397_chip *pmic;
|
||||
|
||||
mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL);
|
||||
if (!mt6397)
|
||||
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
mt6397->dev = &pdev->dev;
|
||||
pmic->dev = &pdev->dev;
|
||||
|
||||
/*
|
||||
* mt6397 MFD is child device of soc pmic wrapper.
|
||||
* Regmap is set from its parent.
|
||||
*/
|
||||
mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!mt6397->regmap)
|
||||
pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!pmic->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
platform_set_drvdata(pdev, mt6397);
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
mt6397->irq = platform_get_irq(pdev, 0);
|
||||
if (mt6397->irq > 0) {
|
||||
ret = mt6397_irq_init(mt6397);
|
||||
ret = regmap_read(pmic->regmap, MT6397_CID, &id);
|
||||
if (ret) {
|
||||
dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
|
||||
goto fail_irq;
|
||||
}
|
||||
|
||||
switch (id & 0xff) {
|
||||
case MT6323_CID_CODE:
|
||||
pmic->int_con[0] = MT6323_INT_CON0;
|
||||
pmic->int_con[1] = MT6323_INT_CON1;
|
||||
pmic->int_status[0] = MT6323_INT_STATUS0;
|
||||
pmic->int_status[1] = MT6323_INT_STATUS1;
|
||||
ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
||||
ARRAY_SIZE(mt6323_devs), NULL, 0, NULL);
|
||||
break;
|
||||
|
||||
case MT6397_CID_CODE:
|
||||
case MT6391_CID_CODE:
|
||||
pmic->int_con[0] = MT6397_INT_CON0;
|
||||
pmic->int_con[1] = MT6397_INT_CON1;
|
||||
pmic->int_status[0] = MT6397_INT_STATUS0;
|
||||
pmic->int_status[1] = MT6397_INT_STATUS1;
|
||||
ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&pdev->dev, "unsupported chip: %d\n", id);
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
||||
pmic->irq = platform_get_irq(pdev, 0);
|
||||
if (pmic->irq > 0) {
|
||||
ret = mt6397_irq_init(pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
|
||||
if (ret)
|
||||
fail_irq:
|
||||
if (ret) {
|
||||
irq_domain_remove(pmic->irq_domain);
|
||||
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -271,10 +321,17 @@ static int mt6397_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id mt6397_of_match[] = {
|
||||
{ .compatible = "mediatek,mt6397" },
|
||||
{ .compatible = "mediatek,mt6323" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt6397_of_match);
|
||||
|
||||
static const struct platform_device_id mt6397_id[] = {
|
||||
{ "mt6397", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, mt6397_id);
|
||||
|
||||
static struct platform_driver mt6397_driver = {
|
||||
.probe = mt6397_probe,
|
||||
.remove = mt6397_remove,
|
||||
@ -283,6 +340,7 @@ static struct platform_driver mt6397_driver = {
|
||||
.of_match_table = of_match_ptr(mt6397_of_match),
|
||||
.pm = &mt6397_pm_ops,
|
||||
},
|
||||
.id_table = mt6397_id,
|
||||
};
|
||||
|
||||
module_platform_driver(mt6397_driver);
|
||||
@ -290,4 +348,3 @@ module_platform_driver(mt6397_driver);
|
||||
MODULE_AUTHOR("Flora Fu, MediaTek");
|
||||
MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:mt6397");
|
||||
|
@ -241,8 +241,8 @@ static const struct regmap_config rc5t583_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.volatile_reg = volatile_reg,
|
||||
.max_register = RC5T583_MAX_REGS,
|
||||
.num_reg_defaults_raw = RC5T583_MAX_REGS,
|
||||
.max_register = RC5T583_MAX_REG,
|
||||
.num_reg_defaults_raw = RC5T583_NUM_REGS,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
|
@ -333,6 +333,31 @@ static const struct mfd_cell stmpe_keypad_cell = {
|
||||
.num_resources = ARRAY_SIZE(stmpe_keypad_resources),
|
||||
};
|
||||
|
||||
/*
|
||||
* PWM (1601, 2401, 2403)
|
||||
*/
|
||||
static struct resource stmpe_pwm_resources[] = {
|
||||
{
|
||||
.name = "PWM0",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "PWM1",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "PWM2",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell stmpe_pwm_cell = {
|
||||
.name = "stmpe-pwm",
|
||||
.of_compatible = "st,stmpe-pwm",
|
||||
.resources = stmpe_pwm_resources,
|
||||
.num_resources = ARRAY_SIZE(stmpe_pwm_resources),
|
||||
};
|
||||
|
||||
/*
|
||||
* STMPE801
|
||||
*/
|
||||
@ -537,6 +562,11 @@ static struct stmpe_variant_block stmpe1601_blocks[] = {
|
||||
.irq = STMPE1601_IRQ_KEYPAD,
|
||||
.block = STMPE_BLOCK_KEYPAD,
|
||||
},
|
||||
{
|
||||
.cell = &stmpe_pwm_cell,
|
||||
.irq = STMPE1601_IRQ_PWM0,
|
||||
.block = STMPE_BLOCK_PWM,
|
||||
},
|
||||
};
|
||||
|
||||
/* supported autosleep timeout delay (in msecs) */
|
||||
@ -771,6 +801,11 @@ static struct stmpe_variant_block stmpe24xx_blocks[] = {
|
||||
.irq = STMPE24XX_IRQ_KEYPAD,
|
||||
.block = STMPE_BLOCK_KEYPAD,
|
||||
},
|
||||
{
|
||||
.cell = &stmpe_pwm_cell,
|
||||
.irq = STMPE24XX_IRQ_PWM0,
|
||||
.block = STMPE_BLOCK_PWM,
|
||||
},
|
||||
};
|
||||
|
||||
static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
|
||||
|
@ -36,7 +36,7 @@ struct syscon {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static struct regmap_config syscon_regmap_config = {
|
||||
static const struct regmap_config syscon_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -50,6 +50,7 @@ static struct syscon *of_syscon_register(struct device_node *np)
|
||||
u32 reg_io_width;
|
||||
int ret;
|
||||
struct regmap_config syscon_config = syscon_regmap_config;
|
||||
struct resource res;
|
||||
|
||||
if (!of_device_is_compatible(np, "syscon"))
|
||||
return ERR_PTR(-EINVAL);
|
||||
@ -58,7 +59,12 @@ static struct syscon *of_syscon_register(struct device_node *np)
|
||||
if (!syscon)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
if (of_address_to_resource(np, 0, &res)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_map;
|
||||
}
|
||||
|
||||
base = ioremap(res.start, resource_size(&res));
|
||||
if (!base) {
|
||||
ret = -ENOMEM;
|
||||
goto err_map;
|
||||
@ -81,6 +87,7 @@ static struct syscon *of_syscon_register(struct device_node *np)
|
||||
|
||||
syscon_config.reg_stride = reg_io_width;
|
||||
syscon_config.val_bits = reg_io_width * 8;
|
||||
syscon_config.max_register = resource_size(&res) - reg_io_width;
|
||||
|
||||
regmap = regmap_init_mmio(NULL, base, &syscon_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
@ -192,6 +199,7 @@ static int syscon_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct syscon_platform_data *pdata = dev_get_platdata(dev);
|
||||
struct syscon *syscon;
|
||||
struct regmap_config syscon_config = syscon_regmap_config;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
@ -207,11 +215,10 @@ static int syscon_probe(struct platform_device *pdev)
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
syscon_regmap_config.max_register = res->end - res->start - 3;
|
||||
syscon_config.max_register = res->end - res->start - 3;
|
||||
if (pdata)
|
||||
syscon_regmap_config.name = pdata->label;
|
||||
syscon->regmap = devm_regmap_init_mmio(dev, base,
|
||||
&syscon_regmap_config);
|
||||
syscon_config.name = pdata->label;
|
||||
syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
|
||||
if (IS_ERR(syscon->regmap)) {
|
||||
dev_err(dev, "regmap init failed\n");
|
||||
return PTR_ERR(syscon->regmap);
|
||||
|
@ -1059,26 +1059,7 @@ EXPORT_SYMBOL(tps65013_set_low_pwr);
|
||||
|
||||
static int __init tps_init(void)
|
||||
{
|
||||
u32 tries = 3;
|
||||
int status = -ENODEV;
|
||||
|
||||
printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION);
|
||||
|
||||
/* some boards have startup glitches */
|
||||
while (tries--) {
|
||||
status = i2c_add_driver(&tps65010_driver);
|
||||
if (the_tps)
|
||||
break;
|
||||
i2c_del_driver(&tps65010_driver);
|
||||
if (!tries) {
|
||||
printk(KERN_ERR "%s: no chip?\n", DRIVER_NAME);
|
||||
return -ENODEV;
|
||||
}
|
||||
pr_debug("%s: re-probe ...\n", DRIVER_NAME);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
return status;
|
||||
return i2c_add_driver(&tps65010_driver);
|
||||
}
|
||||
/* NOTE: this MUST be initialized before the other parts of the system
|
||||
* that rely on it ... but after the i2c bus on which this relies.
|
||||
|
149
drivers/mfd/tps65086.c
Normal file
149
drivers/mfd/tps65086.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Andrew F. Davis <afd@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether expressed or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License version 2 for more details.
|
||||
*
|
||||
* Based on the TPS65912 driver
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/mfd/tps65086.h>
|
||||
|
||||
static const struct mfd_cell tps65086_cells[] = {
|
||||
{ .name = "tps65086-regulator", },
|
||||
{ .name = "tps65086-gpio", },
|
||||
};
|
||||
|
||||
static const struct regmap_range tps65086_yes_ranges[] = {
|
||||
regmap_reg_range(TPS65086_IRQ, TPS65086_IRQ),
|
||||
regmap_reg_range(TPS65086_PMICSTAT, TPS65086_SHUTDNSRC),
|
||||
regmap_reg_range(TPS65086_GPOCTRL, TPS65086_GPOCTRL),
|
||||
regmap_reg_range(TPS65086_PG_STATUS1, TPS65086_OC_STATUS),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tps65086_volatile_table = {
|
||||
.yes_ranges = tps65086_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(tps65086_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config tps65086_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_table = &tps65086_volatile_table,
|
||||
};
|
||||
|
||||
static const struct regmap_irq tps65086_irqs[] = {
|
||||
REGMAP_IRQ_REG(TPS65086_IRQ_DIETEMP, 0, TPS65086_IRQ_DIETEMP_MASK),
|
||||
REGMAP_IRQ_REG(TPS65086_IRQ_SHUTDN, 0, TPS65086_IRQ_SHUTDN_MASK),
|
||||
REGMAP_IRQ_REG(TPS65086_IRQ_FAULT, 0, TPS65086_IRQ_FAULT_MASK),
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip tps65086_irq_chip = {
|
||||
.name = "tps65086",
|
||||
.status_base = TPS65086_IRQ,
|
||||
.mask_base = TPS65086_IRQ_MASK,
|
||||
.ack_base = TPS65086_IRQ,
|
||||
.init_ack_masked = true,
|
||||
.num_regs = 1,
|
||||
.irqs = tps65086_irqs,
|
||||
.num_irqs = ARRAY_SIZE(tps65086_irqs),
|
||||
};
|
||||
|
||||
static const struct of_device_id tps65086_of_match_table[] = {
|
||||
{ .compatible = "ti,tps65086", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
|
||||
|
||||
static int tps65086_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *ids)
|
||||
{
|
||||
struct tps65086 *tps;
|
||||
unsigned int version;
|
||||
int ret;
|
||||
|
||||
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, tps);
|
||||
tps->dev = &client->dev;
|
||||
tps->irq = client->irq;
|
||||
|
||||
tps->regmap = devm_regmap_init_i2c(client, &tps65086_regmap_config);
|
||||
if (IS_ERR(tps->regmap)) {
|
||||
dev_err(tps->dev, "Failed to initialize register map\n");
|
||||
return PTR_ERR(tps->regmap);
|
||||
}
|
||||
|
||||
ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to read revision register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
|
||||
(version & TPS65086_DEVICEID_PART_MASK),
|
||||
(char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
|
||||
(version & TPS65086_DEVICEID_REV_MASK) >> 6);
|
||||
|
||||
ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
|
||||
&tps65086_irq_chip, &tps->irq_data);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to register IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65086_cells,
|
||||
ARRAY_SIZE(tps65086_cells), NULL, 0,
|
||||
regmap_irq_get_domain(tps->irq_data));
|
||||
if (ret) {
|
||||
regmap_del_irq_chip(tps->irq, tps->irq_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65086_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tps65086 *tps = i2c_get_clientdata(client);
|
||||
|
||||
regmap_del_irq_chip(tps->irq, tps->irq_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65086_id_table[] = {
|
||||
{ "tps65086", 0 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tps65086_id_table);
|
||||
|
||||
static struct i2c_driver tps65086_driver = {
|
||||
.driver = {
|
||||
.name = "tps65086",
|
||||
.of_match_table = tps65086_of_match_table,
|
||||
},
|
||||
.probe = tps65086_probe,
|
||||
.remove = tps65086_remove,
|
||||
.id_table = tps65086_id_table,
|
||||
};
|
||||
module_i2c_driver(tps65086_driver);
|
||||
|
||||
MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
|
||||
MODULE_DESCRIPTION("TPS65086 PMIC Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -30,7 +30,6 @@
|
||||
#include <linux/err.h>
|
||||
|
||||
#define NUM_INT_REG 2
|
||||
#define TOTAL_NUM_REG 0x18
|
||||
|
||||
#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1
|
||||
#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2
|
||||
@ -161,8 +160,8 @@ static bool is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
static const struct regmap_config tps65090_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = TOTAL_NUM_REG,
|
||||
.num_reg_defaults_raw = TOTAL_NUM_REG,
|
||||
.max_register = TPS65090_MAX_REG,
|
||||
.num_reg_defaults_raw = TPS65090_NUM_REGS,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = is_volatile_reg,
|
||||
};
|
||||
|
@ -297,7 +297,6 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
|
||||
{ 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */
|
||||
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
|
||||
{ 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */
|
||||
{ 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */
|
||||
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
|
||||
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
|
||||
@ -314,7 +313,6 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
|
||||
{ 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */
|
||||
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
|
||||
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
|
||||
{ 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */
|
||||
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
|
||||
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
|
||||
@ -338,7 +336,7 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
|
||||
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
|
||||
{ 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
|
||||
{ 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */
|
||||
{ 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */
|
||||
{ 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
|
||||
{ 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */
|
||||
{ 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */
|
||||
@ -402,7 +400,7 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
|
||||
{ 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */
|
||||
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
|
||||
{ 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
|
||||
{ 0x00000440, 0x0FFF }, /* R1088 - DRE Enable */
|
||||
{ 0x00000442, 0x3F0A }, /* R1090 - DRE Control 2 */
|
||||
{ 0x00000443, 0xDC1F }, /* R1090 - DRE Control 3 */
|
||||
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
|
||||
@ -863,7 +861,7 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */
|
||||
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
|
||||
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
|
||||
{ 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
|
||||
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
|
||||
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
|
||||
@ -984,7 +982,7 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||
{ 0x00000ECD, 0x0000 }, /* R3789 - HPLPF4_2 */
|
||||
{ 0x00000EE0, 0x0000 }, /* R3808 - ASRC_ENABLE */
|
||||
{ 0x00000EE2, 0x0000 }, /* R3810 - ASRC_RATE1 */
|
||||
{ 0x00000EE3, 0x0400 }, /* R3811 - ASRC_RATE2 */
|
||||
{ 0x00000EE3, 0x4000 }, /* R3811 - ASRC_RATE2 */
|
||||
{ 0x00000EF0, 0x0000 }, /* R3824 - ISRC 1 CTRL 1 */
|
||||
{ 0x00000EF1, 0x0000 }, /* R3825 - ISRC 1 CTRL 2 */
|
||||
{ 0x00000EF2, 0x0000 }, /* R3826 - ISRC 1 CTRL 3 */
|
||||
@ -1062,8 +1060,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL1_CONTROL_4:
|
||||
case ARIZONA_FLL1_CONTROL_5:
|
||||
case ARIZONA_FLL1_CONTROL_6:
|
||||
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL1_CONTROL_7:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_2:
|
||||
@ -1080,8 +1076,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL2_CONTROL_4:
|
||||
case ARIZONA_FLL2_CONTROL_5:
|
||||
case ARIZONA_FLL2_CONTROL_6:
|
||||
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_CONTROL_7:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_2:
|
||||
@ -1849,8 +1843,6 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_HAPTICS_STATUS:
|
||||
case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS:
|
||||
case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_DAC_COMP_1:
|
||||
case ARIZONA_DAC_COMP_2:
|
||||
case ARIZONA_DAC_COMP_3:
|
||||
|
@ -676,8 +676,8 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */
|
||||
{ 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */
|
||||
{ 0x0000000A, 0x0001 }, /* R10 - Ctrl IF I2C2 CFG 1 */
|
||||
{ 0x0000000B, 0x0036 }, /* R11 - Ctrl IF I2C1 CFG 2 */
|
||||
{ 0x0000000C, 0x0036 }, /* R12 - Ctrl IF I2C2 CFG 2 */
|
||||
{ 0x0000000B, 0x001A }, /* R11 - Ctrl IF I2C1 CFG 2 */
|
||||
{ 0x0000000C, 0x001A }, /* R12 - Ctrl IF I2C2 CFG 2 */
|
||||
{ 0x00000020, 0x0000 }, /* R32 - Tone Generator 1 */
|
||||
{ 0x00000021, 0x1000 }, /* R33 - Tone Generator 2 */
|
||||
{ 0x00000022, 0x0000 }, /* R34 - Tone Generator 3 */
|
||||
@ -723,14 +723,12 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */
|
||||
{ 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */
|
||||
{ 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */
|
||||
{ 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */
|
||||
{ 0x00000171, 0x0002 }, /* R369 - FLL1 Control 1 */
|
||||
{ 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */
|
||||
{ 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */
|
||||
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
|
||||
{ 0x00000175, 0x0006 }, /* R373 - FLL1 Control 5 */
|
||||
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
|
||||
{ 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */
|
||||
{ 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
|
||||
{ 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */
|
||||
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
|
||||
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
|
||||
@ -740,15 +738,13 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */
|
||||
{ 0x00000187, 0x0001 }, /* R390 - FLL1 Synchroniser 7 */
|
||||
{ 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */
|
||||
{ 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */
|
||||
{ 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */
|
||||
{ 0x0000018A, 0x000C }, /* R394 - FLL1 GPIO Clock */
|
||||
{ 0x00000191, 0x0002 }, /* R401 - FLL2 Control 1 */
|
||||
{ 0x00000192, 0x0008 }, /* R402 - FLL2 Control 2 */
|
||||
{ 0x00000193, 0x0018 }, /* R403 - FLL2 Control 3 */
|
||||
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
|
||||
{ 0x00000195, 0x000C }, /* R405 - FLL2 Control 5 */
|
||||
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
|
||||
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
|
||||
{ 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
|
||||
{ 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */
|
||||
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
|
||||
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
|
||||
@ -758,7 +754,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */
|
||||
{ 0x000001A7, 0x0001 }, /* R422 - FLL2 Synchroniser 7 */
|
||||
{ 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */
|
||||
{ 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */
|
||||
{ 0x000001AA, 0x000C }, /* R426 - FLL2 GPIO Clock */
|
||||
{ 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */
|
||||
{ 0x00000210, 0x0184 }, /* R528 - LDO1 Control 1 */
|
||||
{ 0x00000213, 0x03E4 }, /* R531 - LDO2 Control 1 */
|
||||
@ -771,9 +767,9 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
|
||||
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
|
||||
{ 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
|
||||
{ 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */
|
||||
{ 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */
|
||||
{ 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
|
||||
{ 0x000002A9, 0x300A }, /* R681 - Mic Detect Level 4 */
|
||||
{ 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */
|
||||
{ 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */
|
||||
{ 0x000002CB, 0x0000 }, /* R715 - Isolation control */
|
||||
{ 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */
|
||||
@ -810,53 +806,53 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000409, 0x0022 }, /* R1033 - Output Volume Ramp */
|
||||
{ 0x00000410, 0x0080 }, /* R1040 - Output Path Config 1L */
|
||||
{ 0x00000411, 0x0180 }, /* R1041 - DAC Digital Volume 1L */
|
||||
{ 0x00000412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */
|
||||
{ 0x00000412, 0x0081 }, /* R1042 - DAC Volume Limit 1L */
|
||||
{ 0x00000413, 0x0001 }, /* R1043 - Noise Gate Select 1L */
|
||||
{ 0x00000414, 0x0080 }, /* R1044 - Output Path Config 1R */
|
||||
{ 0x00000415, 0x0180 }, /* R1045 - DAC Digital Volume 1R */
|
||||
{ 0x00000416, 0x0080 }, /* R1046 - DAC Volume Limit 1R */
|
||||
{ 0x00000416, 0x0081 }, /* R1046 - DAC Volume Limit 1R */
|
||||
{ 0x00000417, 0x0002 }, /* R1047 - Noise Gate Select 1R */
|
||||
{ 0x00000418, 0x0080 }, /* R1048 - Output Path Config 2L */
|
||||
{ 0x00000419, 0x0180 }, /* R1049 - DAC Digital Volume 2L */
|
||||
{ 0x0000041A, 0x0080 }, /* R1050 - DAC Volume Limit 2L */
|
||||
{ 0x0000041A, 0x0081 }, /* R1050 - DAC Volume Limit 2L */
|
||||
{ 0x0000041B, 0x0004 }, /* R1051 - Noise Gate Select 2L */
|
||||
{ 0x0000041C, 0x0080 }, /* R1052 - Output Path Config 2R */
|
||||
{ 0x0000041D, 0x0180 }, /* R1053 - DAC Digital Volume 2R */
|
||||
{ 0x0000041E, 0x0080 }, /* R1054 - DAC Volume Limit 2R */
|
||||
{ 0x0000041E, 0x0081 }, /* R1054 - DAC Volume Limit 2R */
|
||||
{ 0x0000041F, 0x0008 }, /* R1055 - Noise Gate Select 2R */
|
||||
{ 0x00000420, 0x0080 }, /* R1056 - Output Path Config 3L */
|
||||
{ 0x00000421, 0x0180 }, /* R1057 - DAC Digital Volume 3L */
|
||||
{ 0x00000422, 0x0080 }, /* R1058 - DAC Volume Limit 3L */
|
||||
{ 0x00000422, 0x0081 }, /* R1058 - DAC Volume Limit 3L */
|
||||
{ 0x00000423, 0x0010 }, /* R1059 - Noise Gate Select 3L */
|
||||
{ 0x00000424, 0x0080 }, /* R1060 - Output Path Config 3R */
|
||||
{ 0x00000425, 0x0180 }, /* R1061 - DAC Digital Volume 3R */
|
||||
{ 0x00000426, 0x0080 }, /* R1062 - DAC Volume Limit 3R */
|
||||
{ 0x00000426, 0x0081 }, /* R1062 - DAC Volume Limit 3R */
|
||||
{ 0x00000427, 0x0020 }, /* R1063 - Noise Gate Select 3R */
|
||||
{ 0x00000428, 0x0000 }, /* R1064 - Output Path Config 4L */
|
||||
{ 0x00000429, 0x0180 }, /* R1065 - DAC Digital Volume 4L */
|
||||
{ 0x0000042A, 0x0080 }, /* R1066 - Out Volume 4L */
|
||||
{ 0x0000042A, 0x0081 }, /* R1066 - Out Volume 4L */
|
||||
{ 0x0000042B, 0x0040 }, /* R1067 - Noise Gate Select 4L */
|
||||
{ 0x0000042C, 0x0000 }, /* R1068 - Output Path Config 4R */
|
||||
{ 0x0000042D, 0x0180 }, /* R1069 - DAC Digital Volume 4R */
|
||||
{ 0x0000042E, 0x0080 }, /* R1070 - Out Volume 4R */
|
||||
{ 0x0000042E, 0x0081 }, /* R1070 - Out Volume 4R */
|
||||
{ 0x0000042F, 0x0080 }, /* R1071 - Noise Gate Select 4R */
|
||||
{ 0x00000430, 0x0000 }, /* R1072 - Output Path Config 5L */
|
||||
{ 0x00000431, 0x0180 }, /* R1073 - DAC Digital Volume 5L */
|
||||
{ 0x00000432, 0x0080 }, /* R1074 - DAC Volume Limit 5L */
|
||||
{ 0x00000432, 0x0081 }, /* R1074 - DAC Volume Limit 5L */
|
||||
{ 0x00000433, 0x0100 }, /* R1075 - Noise Gate Select 5L */
|
||||
{ 0x00000434, 0x0000 }, /* R1076 - Output Path Config 5R */
|
||||
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
|
||||
{ 0x00000436, 0x0080 }, /* R1078 - DAC Volume Limit 5R */
|
||||
{ 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */
|
||||
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
|
||||
{ 0x00000438, 0x0000 }, /* R1080 - Output Path Config 6L */
|
||||
{ 0x00000439, 0x0180 }, /* R1081 - DAC Digital Volume 6L */
|
||||
{ 0x0000043A, 0x0080 }, /* R1082 - DAC Volume Limit 6L */
|
||||
{ 0x0000043A, 0x0081 }, /* R1082 - DAC Volume Limit 6L */
|
||||
{ 0x0000043B, 0x0400 }, /* R1083 - Noise Gate Select 6L */
|
||||
{ 0x0000043C, 0x0000 }, /* R1084 - Output Path Config 6R */
|
||||
{ 0x0000043D, 0x0180 }, /* R1085 - DAC Digital Volume 6R */
|
||||
{ 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
|
||||
{ 0x0000043E, 0x0081 }, /* R1086 - DAC Volume Limit 6R */
|
||||
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
|
||||
{ 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
|
||||
{ 0x00000440, 0x003F }, /* R1088 - DRE Enable */
|
||||
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
|
||||
{ 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */
|
||||
{ 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
|
||||
@ -864,8 +860,8 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000492, 0x0069 }, /* R1170 - PDM SPK2 CTRL 1 */
|
||||
{ 0x00000493, 0x0000 }, /* R1171 - PDM SPK2 CTRL 2 */
|
||||
{ 0x000004A0, 0x3480 }, /* R1184 - HP1 Short Circuit Ctrl */
|
||||
{ 0x000004A1, 0x3480 }, /* R1185 - HP2 Short Circuit Ctrl */
|
||||
{ 0x000004A2, 0x3480 }, /* R1186 - HP3 Short Circuit Ctrl */
|
||||
{ 0x000004A1, 0x3400 }, /* R1185 - HP2 Short Circuit Ctrl */
|
||||
{ 0x000004A2, 0x3400 }, /* R1186 - HP3 Short Circuit Ctrl */
|
||||
{ 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */
|
||||
{ 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */
|
||||
{ 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */
|
||||
@ -1483,23 +1479,23 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
|
||||
{ 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */
|
||||
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
|
||||
{ 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
|
||||
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
|
||||
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
|
||||
{ 0x00000C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 6 */
|
||||
{ 0x00000C30, 0x8282 }, /* R3120 - Misc Pad Ctrl 7 */
|
||||
{ 0x00000C31, 0x0082 }, /* R3121 - Misc Pad Ctrl 8 */
|
||||
{ 0x00000C32, 0x8282 }, /* R3122 - Misc Pad Ctrl 9 */
|
||||
{ 0x00000C33, 0x8282 }, /* R3123 - Misc Pad Ctrl 10 */
|
||||
{ 0x00000C34, 0x8282 }, /* R3124 - Misc Pad Ctrl 11 */
|
||||
{ 0x00000C35, 0x8282 }, /* R3125 - Misc Pad Ctrl 12 */
|
||||
{ 0x00000C36, 0x8282 }, /* R3126 - Misc Pad Ctrl 13 */
|
||||
{ 0x00000C37, 0x8282 }, /* R3127 - Misc Pad Ctrl 14 */
|
||||
{ 0x00000C38, 0x8282 }, /* R3128 - Misc Pad Ctrl 15 */
|
||||
{ 0x00000C39, 0x8282 }, /* R3129 - Misc Pad Ctrl 16 */
|
||||
{ 0x00000C3A, 0x8282 }, /* R3130 - Misc Pad Ctrl 17 */
|
||||
{ 0x00000C3B, 0x8282 }, /* R3131 - Misc Pad Ctrl 18 */
|
||||
{ 0x00000C30, 0x0404 }, /* R3120 - Misc Pad Ctrl 7 */
|
||||
{ 0x00000C31, 0x0004 }, /* R3121 - Misc Pad Ctrl 8 */
|
||||
{ 0x00000C32, 0x0404 }, /* R3122 - Misc Pad Ctrl 9 */
|
||||
{ 0x00000C33, 0x0404 }, /* R3123 - Misc Pad Ctrl 10 */
|
||||
{ 0x00000C34, 0x0404 }, /* R3124 - Misc Pad Ctrl 11 */
|
||||
{ 0x00000C35, 0x0404 }, /* R3125 - Misc Pad Ctrl 12 */
|
||||
{ 0x00000C36, 0x0404 }, /* R3126 - Misc Pad Ctrl 13 */
|
||||
{ 0x00000C37, 0x0404 }, /* R3127 - Misc Pad Ctrl 14 */
|
||||
{ 0x00000C38, 0x0004 }, /* R3128 - Misc Pad Ctrl 15 */
|
||||
{ 0x00000C39, 0x0404 }, /* R3129 - Misc Pad Ctrl 16 */
|
||||
{ 0x00000C3A, 0x0404 }, /* R3130 - Misc Pad Ctrl 17 */
|
||||
{ 0x00000C3B, 0x0404 }, /* R3131 - Misc Pad Ctrl 18 */
|
||||
{ 0x00000D08, 0xFFFF }, /* R3336 - Interrupt Status 1 Mask */
|
||||
{ 0x00000D09, 0xFFFF }, /* R3337 - Interrupt Status 2 Mask */
|
||||
{ 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */
|
||||
@ -1641,7 +1637,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000F0D, 0x0000 }, /* R3853 - ANC Coefficient */
|
||||
{ 0x00000F0E, 0x0000 }, /* R3854 - ANC Coefficient */
|
||||
{ 0x00000F0F, 0x0000 }, /* R3855 - ANC Coefficient */
|
||||
{ 0x00000F10, 0x0000 }, /* R3856 - ANC Coefficient */
|
||||
{ 0x00000F10, 0x0001 }, /* R3856 - ANC Coefficient */
|
||||
{ 0x00000F11, 0x0000 }, /* R3857 - ANC Coefficient */
|
||||
{ 0x00000F12, 0x0000 }, /* R3858 - ANC Coefficient */
|
||||
{ 0x00000F15, 0x0000 }, /* R3861 - FCL Filter Control */
|
||||
@ -1947,8 +1943,6 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL1_CONTROL_5:
|
||||
case ARIZONA_FLL1_CONTROL_6:
|
||||
case ARIZONA_FLL1_CONTROL_7:
|
||||
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_3:
|
||||
@ -1965,8 +1959,6 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL2_CONTROL_5:
|
||||
case ARIZONA_FLL2_CONTROL_6:
|
||||
case ARIZONA_FLL2_CONTROL_7:
|
||||
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_3:
|
||||
|
@ -229,8 +229,6 @@ static const struct reg_default wm8998_reg_default[] = {
|
||||
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
|
||||
{ 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */
|
||||
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
|
||||
{ 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */
|
||||
{ 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
|
||||
{ 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */
|
||||
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
|
||||
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
|
||||
@ -247,8 +245,6 @@ static const struct reg_default wm8998_reg_default[] = {
|
||||
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
|
||||
{ 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */
|
||||
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
|
||||
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
|
||||
{ 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
|
||||
{ 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */
|
||||
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
|
||||
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
|
||||
@ -320,7 +316,7 @@ static const struct reg_default wm8998_reg_default[] = {
|
||||
{ 0x00000434, 0x0000 }, /* R1076 - Output Path Config 5R */
|
||||
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
|
||||
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
|
||||
{ 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
|
||||
{ 0x00000440, 0x002F }, /* R1088 - DRE Enable */
|
||||
{ 0x00000441, 0xC759 }, /* R1089 - DRE Control 1 */
|
||||
{ 0x00000442, 0x2A08 }, /* R1089 - DRE Control 2 */
|
||||
{ 0x00000443, 0x5CFA }, /* R1089 - DRE Control 3 */
|
||||
@ -686,7 +682,7 @@ static const struct reg_default wm8998_reg_default[] = {
|
||||
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
|
||||
{ 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */
|
||||
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
|
||||
{ 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
|
||||
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
|
||||
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
|
||||
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
|
||||
@ -888,8 +884,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL1_CONTROL_5:
|
||||
case ARIZONA_FLL1_CONTROL_6:
|
||||
case ARIZONA_FLL1_CONTROL_7:
|
||||
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_3:
|
||||
@ -906,8 +900,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_FLL2_CONTROL_5:
|
||||
case ARIZONA_FLL2_CONTROL_6:
|
||||
case ARIZONA_FLL2_CONTROL_7:
|
||||
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_3:
|
||||
|
@ -238,6 +238,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
|
||||
step = 75;
|
||||
break;
|
||||
case AXP221_ID:
|
||||
case AXP223_ID:
|
||||
min = 1800;
|
||||
max = 4050;
|
||||
def = 3000;
|
||||
@ -316,6 +317,7 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
|
||||
break;
|
||||
|
||||
case AXP221_ID:
|
||||
case AXP223_ID:
|
||||
if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
|
||||
return -EINVAL;
|
||||
|
||||
@ -354,6 +356,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
nregulators = AXP20X_REG_ID_MAX;
|
||||
break;
|
||||
case AXP221_ID:
|
||||
case AXP223_ID:
|
||||
regulators = axp22x_regulators;
|
||||
nregulators = AXP22X_REG_ID_MAX;
|
||||
break;
|
||||
|
18
include/dt-bindings/iio/adc/fsl-imx25-gcq.h
Normal file
18
include/dt-bindings/iio/adc/fsl-imx25-gcq.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* This header provides constants for configuring the I.MX25 ADC
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
|
||||
#define _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
|
||||
|
||||
#define MX25_ADC_REFP_YP 0 /* YP voltage reference */
|
||||
#define MX25_ADC_REFP_XP 1 /* XP voltage reference */
|
||||
#define MX25_ADC_REFP_EXT 2 /* External voltage reference */
|
||||
#define MX25_ADC_REFP_INT 3 /* Internal voltage reference */
|
||||
|
||||
#define MX25_ADC_REFN_XN 0 /* XN ground reference */
|
||||
#define MX25_ADC_REFN_YN 1 /* YN ground reference */
|
||||
#define MX25_ADC_REFN_NGND 2 /* Internal ground reference */
|
||||
#define MX25_ADC_REFN_NGND2 3 /* External ground reference */
|
||||
|
||||
#endif
|
@ -51,7 +51,8 @@
|
||||
#define AS3711_ASIC_ID_1 0x90
|
||||
#define AS3711_ASIC_ID_2 0x91
|
||||
|
||||
#define AS3711_MAX_REGS 0x92
|
||||
#define AS3711_MAX_REG AS3711_ASIC_ID_2
|
||||
#define AS3711_NUM_REGS (AS3711_MAX_REG + 1)
|
||||
|
||||
/* Regulators */
|
||||
enum {
|
||||
|
@ -18,6 +18,7 @@ enum {
|
||||
AXP202_ID,
|
||||
AXP209_ID,
|
||||
AXP221_ID,
|
||||
AXP223_ID,
|
||||
AXP288_ID,
|
||||
NR_AXP20X_VARIANTS,
|
||||
};
|
||||
@ -396,7 +397,7 @@ enum axp288_irqs {
|
||||
|
||||
struct axp20x_dev {
|
||||
struct device *dev;
|
||||
struct i2c_client *i2c_client;
|
||||
int irq;
|
||||
struct regmap *regmap;
|
||||
struct regmap_irq_chip_data *regmap_irqc;
|
||||
long variant;
|
||||
@ -462,4 +463,35 @@ static inline int axp20x_read_variable_width(struct regmap *regmap,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* axp20x_match_device(): Setup axp20x variant related fields
|
||||
*
|
||||
* @axp20x: axp20x device to setup (.dev field must be set)
|
||||
* @dev: device associated with this axp20x device
|
||||
*
|
||||
* This lets the axp20x core configure the mfd cells and register maps
|
||||
* for later use.
|
||||
*/
|
||||
int axp20x_match_device(struct axp20x_dev *axp20x);
|
||||
|
||||
/**
|
||||
* axp20x_device_probe(): Probe a configured axp20x device
|
||||
*
|
||||
* @axp20x: axp20x device to probe (must be configured)
|
||||
*
|
||||
* This function lets the axp20x core register the axp20x mfd devices
|
||||
* and irqchip. The axp20x device passed in must be fully configured
|
||||
* with axp20x_match_device, its irq set, and regmap created.
|
||||
*/
|
||||
int axp20x_device_probe(struct axp20x_dev *axp20x);
|
||||
|
||||
/**
|
||||
* axp20x_device_probe(): Remove a axp20x device
|
||||
*
|
||||
* @axp20x: axp20x device to remove
|
||||
*
|
||||
* This tells the axp20x core to remove the associated mfd devices
|
||||
*/
|
||||
int axp20x_device_remove(struct axp20x_dev *axp20x);
|
||||
|
||||
#endif /* __LINUX_MFD_AXP20X_H */
|
||||
|
@ -245,7 +245,7 @@ int cros_ec_remove(struct cros_ec_device *ec_dev);
|
||||
int cros_ec_register(struct cros_ec_device *ec_dev);
|
||||
|
||||
/**
|
||||
* cros_ec_register - Query the protocol version supported by the ChromeOS EC
|
||||
* cros_ec_query_all - Query the protocol version supported by the ChromeOS EC
|
||||
*
|
||||
* @ec_dev: Device to register
|
||||
* @return 0 if ok, -ve on error
|
||||
|
140
include/linux/mfd/imx25-tsadc.h
Normal file
140
include/linux/mfd/imx25-tsadc.h
Normal file
@ -0,0 +1,140 @@
|
||||
#ifndef _LINUX_INCLUDE_MFD_IMX25_TSADC_H_
|
||||
#define _LINUX_INCLUDE_MFD_IMX25_TSADC_H_
|
||||
|
||||
struct regmap;
|
||||
struct clk;
|
||||
|
||||
struct mx25_tsadc {
|
||||
struct regmap *regs;
|
||||
struct irq_domain *domain;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
#define MX25_TSC_TGCR 0x00
|
||||
#define MX25_TSC_TGSR 0x04
|
||||
#define MX25_TSC_TICR 0x08
|
||||
|
||||
/* The same register layout for TC and GC queue */
|
||||
#define MX25_ADCQ_FIFO 0x00
|
||||
#define MX25_ADCQ_CR 0x04
|
||||
#define MX25_ADCQ_SR 0x08
|
||||
#define MX25_ADCQ_MR 0x0c
|
||||
#define MX25_ADCQ_ITEM_7_0 0x20
|
||||
#define MX25_ADCQ_ITEM_15_8 0x24
|
||||
#define MX25_ADCQ_CFG(n) (0x40 + ((n) * 0x4))
|
||||
|
||||
#define MX25_ADCQ_MR_MASK 0xffffffff
|
||||
|
||||
/* TGCR */
|
||||
#define MX25_TGCR_PDBTIME(x) ((x) << 25)
|
||||
#define MX25_TGCR_PDBTIME_MASK GENMASK(31, 25)
|
||||
#define MX25_TGCR_PDBEN BIT(24)
|
||||
#define MX25_TGCR_PDEN BIT(23)
|
||||
#define MX25_TGCR_ADCCLKCFG(x) ((x) << 16)
|
||||
#define MX25_TGCR_GET_ADCCLK(x) (((x) >> 16) & 0x1f)
|
||||
#define MX25_TGCR_INTREFEN BIT(10)
|
||||
#define MX25_TGCR_POWERMODE_MASK GENMASK(9, 8)
|
||||
#define MX25_TGCR_POWERMODE_SAVE (1 << 8)
|
||||
#define MX25_TGCR_POWERMODE_ON (2 << 8)
|
||||
#define MX25_TGCR_STLC BIT(5)
|
||||
#define MX25_TGCR_SLPC BIT(4)
|
||||
#define MX25_TGCR_FUNC_RST BIT(2)
|
||||
#define MX25_TGCR_TSC_RST BIT(1)
|
||||
#define MX25_TGCR_CLK_EN BIT(0)
|
||||
|
||||
/* TGSR */
|
||||
#define MX25_TGSR_SLP_INT BIT(2)
|
||||
#define MX25_TGSR_GCQ_INT BIT(1)
|
||||
#define MX25_TGSR_TCQ_INT BIT(0)
|
||||
|
||||
/* ADCQ_ITEM_* */
|
||||
#define _MX25_ADCQ_ITEM(item, x) ((x) << ((item) * 4))
|
||||
#define MX25_ADCQ_ITEM(item, x) ((item) >= 8 ? \
|
||||
_MX25_ADCQ_ITEM((item) - 8, (x)) : _MX25_ADCQ_ITEM((item), (x)))
|
||||
|
||||
/* ADCQ_FIFO (TCQFIFO and GCQFIFO) */
|
||||
#define MX25_ADCQ_FIFO_DATA(x) (((x) >> 4) & 0xfff)
|
||||
#define MX25_ADCQ_FIFO_ID(x) ((x) & 0xf)
|
||||
|
||||
/* ADCQ_CR (TCQR and GCQR) */
|
||||
#define MX25_ADCQ_CR_PDCFG_LEVEL BIT(19)
|
||||
#define MX25_ADCQ_CR_PDMSK BIT(18)
|
||||
#define MX25_ADCQ_CR_FRST BIT(17)
|
||||
#define MX25_ADCQ_CR_QRST BIT(16)
|
||||
#define MX25_ADCQ_CR_RWAIT_MASK GENMASK(15, 12)
|
||||
#define MX25_ADCQ_CR_RWAIT(x) ((x) << 12)
|
||||
#define MX25_ADCQ_CR_WMRK_MASK GENMASK(11, 8)
|
||||
#define MX25_ADCQ_CR_WMRK(x) ((x) << 8)
|
||||
#define MX25_ADCQ_CR_LITEMID_MASK (0xf << 4)
|
||||
#define MX25_ADCQ_CR_LITEMID(x) ((x) << 4)
|
||||
#define MX25_ADCQ_CR_RPT BIT(3)
|
||||
#define MX25_ADCQ_CR_FQS BIT(2)
|
||||
#define MX25_ADCQ_CR_QSM_MASK GENMASK(1, 0)
|
||||
#define MX25_ADCQ_CR_QSM_PD 0x1
|
||||
#define MX25_ADCQ_CR_QSM_FQS 0x2
|
||||
#define MX25_ADCQ_CR_QSM_FQS_PD 0x3
|
||||
|
||||
/* ADCQ_SR (TCQSR and GCQSR) */
|
||||
#define MX25_ADCQ_SR_FDRY BIT(15)
|
||||
#define MX25_ADCQ_SR_FULL BIT(14)
|
||||
#define MX25_ADCQ_SR_EMPT BIT(13)
|
||||
#define MX25_ADCQ_SR_FDN(x) (((x) >> 8) & 0x1f)
|
||||
#define MX25_ADCQ_SR_FRR BIT(6)
|
||||
#define MX25_ADCQ_SR_FUR BIT(5)
|
||||
#define MX25_ADCQ_SR_FOR BIT(4)
|
||||
#define MX25_ADCQ_SR_EOQ BIT(1)
|
||||
#define MX25_ADCQ_SR_PD BIT(0)
|
||||
|
||||
/* ADCQ_MR (TCQMR and GCQMR) */
|
||||
#define MX25_ADCQ_MR_FDRY_DMA BIT(31)
|
||||
#define MX25_ADCQ_MR_FER_DMA BIT(22)
|
||||
#define MX25_ADCQ_MR_FUR_DMA BIT(21)
|
||||
#define MX25_ADCQ_MR_FOR_DMA BIT(20)
|
||||
#define MX25_ADCQ_MR_EOQ_DMA BIT(17)
|
||||
#define MX25_ADCQ_MR_PD_DMA BIT(16)
|
||||
#define MX25_ADCQ_MR_FDRY_IRQ BIT(15)
|
||||
#define MX25_ADCQ_MR_FER_IRQ BIT(6)
|
||||
#define MX25_ADCQ_MR_FUR_IRQ BIT(5)
|
||||
#define MX25_ADCQ_MR_FOR_IRQ BIT(4)
|
||||
#define MX25_ADCQ_MR_EOQ_IRQ BIT(1)
|
||||
#define MX25_ADCQ_MR_PD_IRQ BIT(0)
|
||||
|
||||
/* ADCQ_CFG (TICR, TCC0-7,GCC0-7) */
|
||||
#define MX25_ADCQ_CFG_SETTLING_TIME(x) ((x) << 24)
|
||||
#define MX25_ADCQ_CFG_IGS (1 << 20)
|
||||
#define MX25_ADCQ_CFG_NOS_MASK GENMASK(19, 16)
|
||||
#define MX25_ADCQ_CFG_NOS(x) (((x) - 1) << 16)
|
||||
#define MX25_ADCQ_CFG_WIPER (1 << 15)
|
||||
#define MX25_ADCQ_CFG_YNLR (1 << 14)
|
||||
#define MX25_ADCQ_CFG_YPLL_HIGH (0 << 12)
|
||||
#define MX25_ADCQ_CFG_YPLL_OFF (1 << 12)
|
||||
#define MX25_ADCQ_CFG_YPLL_LOW (3 << 12)
|
||||
#define MX25_ADCQ_CFG_XNUR_HIGH (0 << 10)
|
||||
#define MX25_ADCQ_CFG_XNUR_OFF (1 << 10)
|
||||
#define MX25_ADCQ_CFG_XNUR_LOW (3 << 10)
|
||||
#define MX25_ADCQ_CFG_XPUL_HIGH (0 << 9)
|
||||
#define MX25_ADCQ_CFG_XPUL_OFF (1 << 9)
|
||||
#define MX25_ADCQ_CFG_REFP(sel) ((sel) << 7)
|
||||
#define MX25_ADCQ_CFG_REFP_YP MX25_ADCQ_CFG_REFP(0)
|
||||
#define MX25_ADCQ_CFG_REFP_XP MX25_ADCQ_CFG_REFP(1)
|
||||
#define MX25_ADCQ_CFG_REFP_EXT MX25_ADCQ_CFG_REFP(2)
|
||||
#define MX25_ADCQ_CFG_REFP_INT MX25_ADCQ_CFG_REFP(3)
|
||||
#define MX25_ADCQ_CFG_REFP_MASK GENMASK(8, 7)
|
||||
#define MX25_ADCQ_CFG_IN(sel) ((sel) << 4)
|
||||
#define MX25_ADCQ_CFG_IN_XP MX25_ADCQ_CFG_IN(0)
|
||||
#define MX25_ADCQ_CFG_IN_YP MX25_ADCQ_CFG_IN(1)
|
||||
#define MX25_ADCQ_CFG_IN_XN MX25_ADCQ_CFG_IN(2)
|
||||
#define MX25_ADCQ_CFG_IN_YN MX25_ADCQ_CFG_IN(3)
|
||||
#define MX25_ADCQ_CFG_IN_WIPER MX25_ADCQ_CFG_IN(4)
|
||||
#define MX25_ADCQ_CFG_IN_AUX0 MX25_ADCQ_CFG_IN(5)
|
||||
#define MX25_ADCQ_CFG_IN_AUX1 MX25_ADCQ_CFG_IN(6)
|
||||
#define MX25_ADCQ_CFG_IN_AUX2 MX25_ADCQ_CFG_IN(7)
|
||||
#define MX25_ADCQ_CFG_REFN(sel) ((sel) << 2)
|
||||
#define MX25_ADCQ_CFG_REFN_XN MX25_ADCQ_CFG_REFN(0)
|
||||
#define MX25_ADCQ_CFG_REFN_YN MX25_ADCQ_CFG_REFN(1)
|
||||
#define MX25_ADCQ_CFG_REFN_NGND MX25_ADCQ_CFG_REFN(2)
|
||||
#define MX25_ADCQ_CFG_REFN_NGND2 MX25_ADCQ_CFG_REFN(3)
|
||||
#define MX25_ADCQ_CFG_REFN_MASK GENMASK(3, 2)
|
||||
#define MX25_ADCQ_CFG_PENIACK (1 << 1)
|
||||
|
||||
#endif /* _LINUX_INCLUDE_MFD_IMX25_TSADC_H_ */
|
36
include/linux/mfd/mt6323/core.h
Normal file
36
include/linux/mfd/mt6323/core.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MFD_MT6323_CORE_H__
|
||||
#define __MFD_MT6323_CORE_H__
|
||||
|
||||
enum MT6323_IRQ_STATUS_numbers {
|
||||
MT6323_IRQ_STATUS_SPKL_AB = 0,
|
||||
MT6323_IRQ_STATUS_SPKL,
|
||||
MT6323_IRQ_STATUS_BAT_L,
|
||||
MT6323_IRQ_STATUS_BAT_H,
|
||||
MT6323_IRQ_STATUS_WATCHDOG,
|
||||
MT6323_IRQ_STATUS_PWRKEY,
|
||||
MT6323_IRQ_STATUS_THR_L,
|
||||
MT6323_IRQ_STATUS_THR_H,
|
||||
MT6323_IRQ_STATUS_VBATON_UNDET,
|
||||
MT6323_IRQ_STATUS_BVALID_DET,
|
||||
MT6323_IRQ_STATUS_CHRDET,
|
||||
MT6323_IRQ_STATUS_OV,
|
||||
MT6323_IRQ_STATUS_LDO = 16,
|
||||
MT6323_IRQ_STATUS_FCHRKEY,
|
||||
MT6323_IRQ_STATUS_ACCDET,
|
||||
MT6323_IRQ_STATUS_AUDIO,
|
||||
MT6323_IRQ_STATUS_RTC,
|
||||
MT6323_IRQ_STATUS_VPROC,
|
||||
MT6323_IRQ_STATUS_VSYS,
|
||||
MT6323_IRQ_STATUS_VPA,
|
||||
MT6323_IRQ_STATUS_NR,
|
||||
};
|
||||
|
||||
#endif /* __MFD_MT6323_CORE_H__ */
|
408
include/linux/mfd/mt6323/registers.h
Normal file
408
include/linux/mfd/mt6323/registers.h
Normal file
@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MFD_MT6323_REGISTERS_H__
|
||||
#define __MFD_MT6323_REGISTERS_H__
|
||||
|
||||
/* PMIC Registers */
|
||||
#define MT6323_CHR_CON0 0x0000
|
||||
#define MT6323_CHR_CON1 0x0002
|
||||
#define MT6323_CHR_CON2 0x0004
|
||||
#define MT6323_CHR_CON3 0x0006
|
||||
#define MT6323_CHR_CON4 0x0008
|
||||
#define MT6323_CHR_CON5 0x000A
|
||||
#define MT6323_CHR_CON6 0x000C
|
||||
#define MT6323_CHR_CON7 0x000E
|
||||
#define MT6323_CHR_CON8 0x0010
|
||||
#define MT6323_CHR_CON9 0x0012
|
||||
#define MT6323_CHR_CON10 0x0014
|
||||
#define MT6323_CHR_CON11 0x0016
|
||||
#define MT6323_CHR_CON12 0x0018
|
||||
#define MT6323_CHR_CON13 0x001A
|
||||
#define MT6323_CHR_CON14 0x001C
|
||||
#define MT6323_CHR_CON15 0x001E
|
||||
#define MT6323_CHR_CON16 0x0020
|
||||
#define MT6323_CHR_CON17 0x0022
|
||||
#define MT6323_CHR_CON18 0x0024
|
||||
#define MT6323_CHR_CON19 0x0026
|
||||
#define MT6323_CHR_CON20 0x0028
|
||||
#define MT6323_CHR_CON21 0x002A
|
||||
#define MT6323_CHR_CON22 0x002C
|
||||
#define MT6323_CHR_CON23 0x002E
|
||||
#define MT6323_CHR_CON24 0x0030
|
||||
#define MT6323_CHR_CON25 0x0032
|
||||
#define MT6323_CHR_CON26 0x0034
|
||||
#define MT6323_CHR_CON27 0x0036
|
||||
#define MT6323_CHR_CON28 0x0038
|
||||
#define MT6323_CHR_CON29 0x003A
|
||||
#define MT6323_STRUP_CON0 0x003C
|
||||
#define MT6323_STRUP_CON2 0x003E
|
||||
#define MT6323_STRUP_CON3 0x0040
|
||||
#define MT6323_STRUP_CON4 0x0042
|
||||
#define MT6323_STRUP_CON5 0x0044
|
||||
#define MT6323_STRUP_CON6 0x0046
|
||||
#define MT6323_STRUP_CON7 0x0048
|
||||
#define MT6323_STRUP_CON8 0x004A
|
||||
#define MT6323_STRUP_CON9 0x004C
|
||||
#define MT6323_STRUP_CON10 0x004E
|
||||
#define MT6323_STRUP_CON11 0x0050
|
||||
#define MT6323_SPK_CON0 0x0052
|
||||
#define MT6323_SPK_CON1 0x0054
|
||||
#define MT6323_SPK_CON2 0x0056
|
||||
#define MT6323_SPK_CON6 0x005E
|
||||
#define MT6323_SPK_CON7 0x0060
|
||||
#define MT6323_SPK_CON8 0x0062
|
||||
#define MT6323_SPK_CON9 0x0064
|
||||
#define MT6323_SPK_CON10 0x0066
|
||||
#define MT6323_SPK_CON11 0x0068
|
||||
#define MT6323_SPK_CON12 0x006A
|
||||
#define MT6323_CID 0x0100
|
||||
#define MT6323_TOP_CKPDN0 0x0102
|
||||
#define MT6323_TOP_CKPDN0_SET 0x0104
|
||||
#define MT6323_TOP_CKPDN0_CLR 0x0106
|
||||
#define MT6323_TOP_CKPDN1 0x0108
|
||||
#define MT6323_TOP_CKPDN1_SET 0x010A
|
||||
#define MT6323_TOP_CKPDN1_CLR 0x010C
|
||||
#define MT6323_TOP_CKPDN2 0x010E
|
||||
#define MT6323_TOP_CKPDN2_SET 0x0110
|
||||
#define MT6323_TOP_CKPDN2_CLR 0x0112
|
||||
#define MT6323_TOP_RST_CON 0x0114
|
||||
#define MT6323_TOP_RST_CON_SET 0x0116
|
||||
#define MT6323_TOP_RST_CON_CLR 0x0118
|
||||
#define MT6323_TOP_RST_MISC 0x011A
|
||||
#define MT6323_TOP_RST_MISC_SET 0x011C
|
||||
#define MT6323_TOP_RST_MISC_CLR 0x011E
|
||||
#define MT6323_TOP_CKCON0 0x0120
|
||||
#define MT6323_TOP_CKCON0_SET 0x0122
|
||||
#define MT6323_TOP_CKCON0_CLR 0x0124
|
||||
#define MT6323_TOP_CKCON1 0x0126
|
||||
#define MT6323_TOP_CKCON1_SET 0x0128
|
||||
#define MT6323_TOP_CKCON1_CLR 0x012A
|
||||
#define MT6323_TOP_CKTST0 0x012C
|
||||
#define MT6323_TOP_CKTST1 0x012E
|
||||
#define MT6323_TOP_CKTST2 0x0130
|
||||
#define MT6323_TEST_OUT 0x0132
|
||||
#define MT6323_TEST_CON0 0x0134
|
||||
#define MT6323_TEST_CON1 0x0136
|
||||
#define MT6323_EN_STATUS0 0x0138
|
||||
#define MT6323_EN_STATUS1 0x013A
|
||||
#define MT6323_OCSTATUS0 0x013C
|
||||
#define MT6323_OCSTATUS1 0x013E
|
||||
#define MT6323_PGSTATUS 0x0140
|
||||
#define MT6323_CHRSTATUS 0x0142
|
||||
#define MT6323_TDSEL_CON 0x0144
|
||||
#define MT6323_RDSEL_CON 0x0146
|
||||
#define MT6323_SMT_CON0 0x0148
|
||||
#define MT6323_SMT_CON1 0x014A
|
||||
#define MT6323_SMT_CON2 0x014C
|
||||
#define MT6323_SMT_CON3 0x014E
|
||||
#define MT6323_SMT_CON4 0x0150
|
||||
#define MT6323_DRV_CON0 0x0152
|
||||
#define MT6323_DRV_CON1 0x0154
|
||||
#define MT6323_DRV_CON2 0x0156
|
||||
#define MT6323_DRV_CON3 0x0158
|
||||
#define MT6323_DRV_CON4 0x015A
|
||||
#define MT6323_SIMLS1_CON 0x015C
|
||||
#define MT6323_SIMLS2_CON 0x015E
|
||||
#define MT6323_INT_CON0 0x0160
|
||||
#define MT6323_INT_CON0_SET 0x0162
|
||||
#define MT6323_INT_CON0_CLR 0x0164
|
||||
#define MT6323_INT_CON1 0x0166
|
||||
#define MT6323_INT_CON1_SET 0x0168
|
||||
#define MT6323_INT_CON1_CLR 0x016A
|
||||
#define MT6323_INT_MISC_CON 0x016C
|
||||
#define MT6323_INT_MISC_CON_SET 0x016E
|
||||
#define MT6323_INT_MISC_CON_CLR 0x0170
|
||||
#define MT6323_INT_STATUS0 0x0172
|
||||
#define MT6323_INT_STATUS1 0x0174
|
||||
#define MT6323_OC_GEAR_0 0x0176
|
||||
#define MT6323_OC_GEAR_1 0x0178
|
||||
#define MT6323_OC_GEAR_2 0x017A
|
||||
#define MT6323_OC_CTL_VPROC 0x017C
|
||||
#define MT6323_OC_CTL_VSYS 0x017E
|
||||
#define MT6323_OC_CTL_VPA 0x0180
|
||||
#define MT6323_FQMTR_CON0 0x0182
|
||||
#define MT6323_FQMTR_CON1 0x0184
|
||||
#define MT6323_FQMTR_CON2 0x0186
|
||||
#define MT6323_RG_SPI_CON 0x0188
|
||||
#define MT6323_DEW_DIO_EN 0x018A
|
||||
#define MT6323_DEW_READ_TEST 0x018C
|
||||
#define MT6323_DEW_WRITE_TEST 0x018E
|
||||
#define MT6323_DEW_CRC_SWRST 0x0190
|
||||
#define MT6323_DEW_CRC_EN 0x0192
|
||||
#define MT6323_DEW_CRC_VAL 0x0194
|
||||
#define MT6323_DEW_DBG_MON_SEL 0x0196
|
||||
#define MT6323_DEW_CIPHER_KEY_SEL 0x0198
|
||||
#define MT6323_DEW_CIPHER_IV_SEL 0x019A
|
||||
#define MT6323_DEW_CIPHER_EN 0x019C
|
||||
#define MT6323_DEW_CIPHER_RDY 0x019E
|
||||
#define MT6323_DEW_CIPHER_MODE 0x01A0
|
||||
#define MT6323_DEW_CIPHER_SWRST 0x01A2
|
||||
#define MT6323_DEW_RDDMY_NO 0x01A4
|
||||
#define MT6323_DEW_RDATA_DLY_SEL 0x01A6
|
||||
#define MT6323_BUCK_CON0 0x0200
|
||||
#define MT6323_BUCK_CON1 0x0202
|
||||
#define MT6323_BUCK_CON2 0x0204
|
||||
#define MT6323_BUCK_CON3 0x0206
|
||||
#define MT6323_BUCK_CON4 0x0208
|
||||
#define MT6323_BUCK_CON5 0x020A
|
||||
#define MT6323_VPROC_CON0 0x020C
|
||||
#define MT6323_VPROC_CON1 0x020E
|
||||
#define MT6323_VPROC_CON2 0x0210
|
||||
#define MT6323_VPROC_CON3 0x0212
|
||||
#define MT6323_VPROC_CON4 0x0214
|
||||
#define MT6323_VPROC_CON5 0x0216
|
||||
#define MT6323_VPROC_CON7 0x021A
|
||||
#define MT6323_VPROC_CON8 0x021C
|
||||
#define MT6323_VPROC_CON9 0x021E
|
||||
#define MT6323_VPROC_CON10 0x0220
|
||||
#define MT6323_VPROC_CON11 0x0222
|
||||
#define MT6323_VPROC_CON12 0x0224
|
||||
#define MT6323_VPROC_CON13 0x0226
|
||||
#define MT6323_VPROC_CON14 0x0228
|
||||
#define MT6323_VPROC_CON15 0x022A
|
||||
#define MT6323_VPROC_CON18 0x0230
|
||||
#define MT6323_VSYS_CON0 0x0232
|
||||
#define MT6323_VSYS_CON1 0x0234
|
||||
#define MT6323_VSYS_CON2 0x0236
|
||||
#define MT6323_VSYS_CON3 0x0238
|
||||
#define MT6323_VSYS_CON4 0x023A
|
||||
#define MT6323_VSYS_CON5 0x023C
|
||||
#define MT6323_VSYS_CON7 0x0240
|
||||
#define MT6323_VSYS_CON8 0x0242
|
||||
#define MT6323_VSYS_CON9 0x0244
|
||||
#define MT6323_VSYS_CON10 0x0246
|
||||
#define MT6323_VSYS_CON11 0x0248
|
||||
#define MT6323_VSYS_CON12 0x024A
|
||||
#define MT6323_VSYS_CON13 0x024C
|
||||
#define MT6323_VSYS_CON14 0x024E
|
||||
#define MT6323_VSYS_CON15 0x0250
|
||||
#define MT6323_VSYS_CON18 0x0256
|
||||
#define MT6323_VPA_CON0 0x0300
|
||||
#define MT6323_VPA_CON1 0x0302
|
||||
#define MT6323_VPA_CON2 0x0304
|
||||
#define MT6323_VPA_CON3 0x0306
|
||||
#define MT6323_VPA_CON4 0x0308
|
||||
#define MT6323_VPA_CON5 0x030A
|
||||
#define MT6323_VPA_CON7 0x030E
|
||||
#define MT6323_VPA_CON8 0x0310
|
||||
#define MT6323_VPA_CON9 0x0312
|
||||
#define MT6323_VPA_CON10 0x0314
|
||||
#define MT6323_VPA_CON11 0x0316
|
||||
#define MT6323_VPA_CON12 0x0318
|
||||
#define MT6323_VPA_CON14 0x031C
|
||||
#define MT6323_VPA_CON16 0x0320
|
||||
#define MT6323_VPA_CON17 0x0322
|
||||
#define MT6323_VPA_CON18 0x0324
|
||||
#define MT6323_VPA_CON19 0x0326
|
||||
#define MT6323_VPA_CON20 0x0328
|
||||
#define MT6323_BUCK_K_CON0 0x032A
|
||||
#define MT6323_BUCK_K_CON1 0x032C
|
||||
#define MT6323_BUCK_K_CON2 0x032E
|
||||
#define MT6323_ISINK0_CON0 0x0330
|
||||
#define MT6323_ISINK0_CON1 0x0332
|
||||
#define MT6323_ISINK0_CON2 0x0334
|
||||
#define MT6323_ISINK0_CON3 0x0336
|
||||
#define MT6323_ISINK1_CON0 0x0338
|
||||
#define MT6323_ISINK1_CON1 0x033A
|
||||
#define MT6323_ISINK1_CON2 0x033C
|
||||
#define MT6323_ISINK1_CON3 0x033E
|
||||
#define MT6323_ISINK2_CON0 0x0340
|
||||
#define MT6323_ISINK2_CON1 0x0342
|
||||
#define MT6323_ISINK2_CON2 0x0344
|
||||
#define MT6323_ISINK2_CON3 0x0346
|
||||
#define MT6323_ISINK3_CON0 0x0348
|
||||
#define MT6323_ISINK3_CON1 0x034A
|
||||
#define MT6323_ISINK3_CON2 0x034C
|
||||
#define MT6323_ISINK3_CON3 0x034E
|
||||
#define MT6323_ISINK_ANA0 0x0350
|
||||
#define MT6323_ISINK_ANA1 0x0352
|
||||
#define MT6323_ISINK_PHASE_DLY 0x0354
|
||||
#define MT6323_ISINK_EN_CTRL 0x0356
|
||||
#define MT6323_ANALDO_CON0 0x0400
|
||||
#define MT6323_ANALDO_CON1 0x0402
|
||||
#define MT6323_ANALDO_CON2 0x0404
|
||||
#define MT6323_ANALDO_CON3 0x0406
|
||||
#define MT6323_ANALDO_CON4 0x0408
|
||||
#define MT6323_ANALDO_CON5 0x040A
|
||||
#define MT6323_ANALDO_CON6 0x040C
|
||||
#define MT6323_ANALDO_CON7 0x040E
|
||||
#define MT6323_ANALDO_CON8 0x0410
|
||||
#define MT6323_ANALDO_CON10 0x0412
|
||||
#define MT6323_ANALDO_CON15 0x0414
|
||||
#define MT6323_ANALDO_CON16 0x0416
|
||||
#define MT6323_ANALDO_CON17 0x0418
|
||||
#define MT6323_ANALDO_CON18 0x041A
|
||||
#define MT6323_ANALDO_CON19 0x041C
|
||||
#define MT6323_ANALDO_CON20 0x041E
|
||||
#define MT6323_ANALDO_CON21 0x0420
|
||||
#define MT6323_DIGLDO_CON0 0x0500
|
||||
#define MT6323_DIGLDO_CON2 0x0502
|
||||
#define MT6323_DIGLDO_CON3 0x0504
|
||||
#define MT6323_DIGLDO_CON5 0x0506
|
||||
#define MT6323_DIGLDO_CON6 0x0508
|
||||
#define MT6323_DIGLDO_CON7 0x050A
|
||||
#define MT6323_DIGLDO_CON8 0x050C
|
||||
#define MT6323_DIGLDO_CON9 0x050E
|
||||
#define MT6323_DIGLDO_CON10 0x0510
|
||||
#define MT6323_DIGLDO_CON11 0x0512
|
||||
#define MT6323_DIGLDO_CON12 0x0514
|
||||
#define MT6323_DIGLDO_CON13 0x0516
|
||||
#define MT6323_DIGLDO_CON14 0x0518
|
||||
#define MT6323_DIGLDO_CON15 0x051A
|
||||
#define MT6323_DIGLDO_CON16 0x051C
|
||||
#define MT6323_DIGLDO_CON17 0x051E
|
||||
#define MT6323_DIGLDO_CON18 0x0520
|
||||
#define MT6323_DIGLDO_CON19 0x0522
|
||||
#define MT6323_DIGLDO_CON20 0x0524
|
||||
#define MT6323_DIGLDO_CON21 0x0526
|
||||
#define MT6323_DIGLDO_CON23 0x0528
|
||||
#define MT6323_DIGLDO_CON24 0x052A
|
||||
#define MT6323_DIGLDO_CON26 0x052C
|
||||
#define MT6323_DIGLDO_CON27 0x052E
|
||||
#define MT6323_DIGLDO_CON28 0x0530
|
||||
#define MT6323_DIGLDO_CON29 0x0532
|
||||
#define MT6323_DIGLDO_CON30 0x0534
|
||||
#define MT6323_DIGLDO_CON31 0x0536
|
||||
#define MT6323_DIGLDO_CON32 0x0538
|
||||
#define MT6323_DIGLDO_CON33 0x053A
|
||||
#define MT6323_DIGLDO_CON34 0x053C
|
||||
#define MT6323_DIGLDO_CON35 0x053E
|
||||
#define MT6323_DIGLDO_CON36 0x0540
|
||||
#define MT6323_DIGLDO_CON39 0x0542
|
||||
#define MT6323_DIGLDO_CON40 0x0544
|
||||
#define MT6323_DIGLDO_CON41 0x0546
|
||||
#define MT6323_DIGLDO_CON42 0x0548
|
||||
#define MT6323_DIGLDO_CON43 0x054A
|
||||
#define MT6323_DIGLDO_CON44 0x054C
|
||||
#define MT6323_DIGLDO_CON45 0x054E
|
||||
#define MT6323_DIGLDO_CON46 0x0550
|
||||
#define MT6323_DIGLDO_CON47 0x0552
|
||||
#define MT6323_DIGLDO_CON48 0x0554
|
||||
#define MT6323_DIGLDO_CON49 0x0556
|
||||
#define MT6323_DIGLDO_CON50 0x0558
|
||||
#define MT6323_DIGLDO_CON51 0x055A
|
||||
#define MT6323_DIGLDO_CON52 0x055C
|
||||
#define MT6323_DIGLDO_CON53 0x055E
|
||||
#define MT6323_DIGLDO_CON54 0x0560
|
||||
#define MT6323_EFUSE_CON0 0x0600
|
||||
#define MT6323_EFUSE_CON1 0x0602
|
||||
#define MT6323_EFUSE_CON2 0x0604
|
||||
#define MT6323_EFUSE_CON3 0x0606
|
||||
#define MT6323_EFUSE_CON4 0x0608
|
||||
#define MT6323_EFUSE_CON5 0x060A
|
||||
#define MT6323_EFUSE_CON6 0x060C
|
||||
#define MT6323_EFUSE_VAL_0_15 0x060E
|
||||
#define MT6323_EFUSE_VAL_16_31 0x0610
|
||||
#define MT6323_EFUSE_VAL_32_47 0x0612
|
||||
#define MT6323_EFUSE_VAL_48_63 0x0614
|
||||
#define MT6323_EFUSE_VAL_64_79 0x0616
|
||||
#define MT6323_EFUSE_VAL_80_95 0x0618
|
||||
#define MT6323_EFUSE_VAL_96_111 0x061A
|
||||
#define MT6323_EFUSE_VAL_112_127 0x061C
|
||||
#define MT6323_EFUSE_VAL_128_143 0x061E
|
||||
#define MT6323_EFUSE_VAL_144_159 0x0620
|
||||
#define MT6323_EFUSE_VAL_160_175 0x0622
|
||||
#define MT6323_EFUSE_VAL_176_191 0x0624
|
||||
#define MT6323_EFUSE_DOUT_0_15 0x0626
|
||||
#define MT6323_EFUSE_DOUT_16_31 0x0628
|
||||
#define MT6323_EFUSE_DOUT_32_47 0x062A
|
||||
#define MT6323_EFUSE_DOUT_48_63 0x062C
|
||||
#define MT6323_EFUSE_DOUT_64_79 0x062E
|
||||
#define MT6323_EFUSE_DOUT_80_95 0x0630
|
||||
#define MT6323_EFUSE_DOUT_96_111 0x0632
|
||||
#define MT6323_EFUSE_DOUT_112_127 0x0634
|
||||
#define MT6323_EFUSE_DOUT_128_143 0x0636
|
||||
#define MT6323_EFUSE_DOUT_144_159 0x0638
|
||||
#define MT6323_EFUSE_DOUT_160_175 0x063A
|
||||
#define MT6323_EFUSE_DOUT_176_191 0x063C
|
||||
#define MT6323_EFUSE_CON7 0x063E
|
||||
#define MT6323_EFUSE_CON8 0x0640
|
||||
#define MT6323_EFUSE_CON9 0x0642
|
||||
#define MT6323_RTC_MIX_CON0 0x0644
|
||||
#define MT6323_RTC_MIX_CON1 0x0646
|
||||
#define MT6323_AUDTOP_CON0 0x0700
|
||||
#define MT6323_AUDTOP_CON1 0x0702
|
||||
#define MT6323_AUDTOP_CON2 0x0704
|
||||
#define MT6323_AUDTOP_CON3 0x0706
|
||||
#define MT6323_AUDTOP_CON4 0x0708
|
||||
#define MT6323_AUDTOP_CON5 0x070A
|
||||
#define MT6323_AUDTOP_CON6 0x070C
|
||||
#define MT6323_AUDTOP_CON7 0x070E
|
||||
#define MT6323_AUDTOP_CON8 0x0710
|
||||
#define MT6323_AUDTOP_CON9 0x0712
|
||||
#define MT6323_AUXADC_ADC0 0x0714
|
||||
#define MT6323_AUXADC_ADC1 0x0716
|
||||
#define MT6323_AUXADC_ADC2 0x0718
|
||||
#define MT6323_AUXADC_ADC3 0x071A
|
||||
#define MT6323_AUXADC_ADC4 0x071C
|
||||
#define MT6323_AUXADC_ADC5 0x071E
|
||||
#define MT6323_AUXADC_ADC6 0x0720
|
||||
#define MT6323_AUXADC_ADC7 0x0722
|
||||
#define MT6323_AUXADC_ADC8 0x0724
|
||||
#define MT6323_AUXADC_ADC9 0x0726
|
||||
#define MT6323_AUXADC_ADC10 0x0728
|
||||
#define MT6323_AUXADC_ADC11 0x072A
|
||||
#define MT6323_AUXADC_ADC12 0x072C
|
||||
#define MT6323_AUXADC_ADC13 0x072E
|
||||
#define MT6323_AUXADC_ADC14 0x0730
|
||||
#define MT6323_AUXADC_ADC15 0x0732
|
||||
#define MT6323_AUXADC_ADC16 0x0734
|
||||
#define MT6323_AUXADC_ADC17 0x0736
|
||||
#define MT6323_AUXADC_ADC18 0x0738
|
||||
#define MT6323_AUXADC_ADC19 0x073A
|
||||
#define MT6323_AUXADC_ADC20 0x073C
|
||||
#define MT6323_AUXADC_RSV1 0x073E
|
||||
#define MT6323_AUXADC_RSV2 0x0740
|
||||
#define MT6323_AUXADC_CON0 0x0742
|
||||
#define MT6323_AUXADC_CON1 0x0744
|
||||
#define MT6323_AUXADC_CON2 0x0746
|
||||
#define MT6323_AUXADC_CON3 0x0748
|
||||
#define MT6323_AUXADC_CON4 0x074A
|
||||
#define MT6323_AUXADC_CON5 0x074C
|
||||
#define MT6323_AUXADC_CON6 0x074E
|
||||
#define MT6323_AUXADC_CON7 0x0750
|
||||
#define MT6323_AUXADC_CON8 0x0752
|
||||
#define MT6323_AUXADC_CON9 0x0754
|
||||
#define MT6323_AUXADC_CON10 0x0756
|
||||
#define MT6323_AUXADC_CON11 0x0758
|
||||
#define MT6323_AUXADC_CON12 0x075A
|
||||
#define MT6323_AUXADC_CON13 0x075C
|
||||
#define MT6323_AUXADC_CON14 0x075E
|
||||
#define MT6323_AUXADC_CON15 0x0760
|
||||
#define MT6323_AUXADC_CON16 0x0762
|
||||
#define MT6323_AUXADC_CON17 0x0764
|
||||
#define MT6323_AUXADC_CON18 0x0766
|
||||
#define MT6323_AUXADC_CON19 0x0768
|
||||
#define MT6323_AUXADC_CON20 0x076A
|
||||
#define MT6323_AUXADC_CON21 0x076C
|
||||
#define MT6323_AUXADC_CON22 0x076E
|
||||
#define MT6323_AUXADC_CON23 0x0770
|
||||
#define MT6323_AUXADC_CON24 0x0772
|
||||
#define MT6323_AUXADC_CON25 0x0774
|
||||
#define MT6323_AUXADC_CON26 0x0776
|
||||
#define MT6323_AUXADC_CON27 0x0778
|
||||
#define MT6323_ACCDET_CON0 0x077A
|
||||
#define MT6323_ACCDET_CON1 0x077C
|
||||
#define MT6323_ACCDET_CON2 0x077E
|
||||
#define MT6323_ACCDET_CON3 0x0780
|
||||
#define MT6323_ACCDET_CON4 0x0782
|
||||
#define MT6323_ACCDET_CON5 0x0784
|
||||
#define MT6323_ACCDET_CON6 0x0786
|
||||
#define MT6323_ACCDET_CON7 0x0788
|
||||
#define MT6323_ACCDET_CON8 0x078A
|
||||
#define MT6323_ACCDET_CON9 0x078C
|
||||
#define MT6323_ACCDET_CON10 0x078E
|
||||
#define MT6323_ACCDET_CON11 0x0790
|
||||
#define MT6323_ACCDET_CON12 0x0792
|
||||
#define MT6323_ACCDET_CON13 0x0794
|
||||
#define MT6323_ACCDET_CON14 0x0796
|
||||
#define MT6323_ACCDET_CON15 0x0798
|
||||
#define MT6323_ACCDET_CON16 0x079A
|
||||
|
||||
#endif /* __MFD_MT6323_REGISTERS_H__ */
|
@ -60,6 +60,8 @@ struct mt6397_chip {
|
||||
u16 wake_mask[2];
|
||||
u16 irq_masks_cur[2];
|
||||
u16 irq_masks_cache[2];
|
||||
u16 int_con[2];
|
||||
u16 int_status[2];
|
||||
};
|
||||
|
||||
#endif /* __MFD_MT6397_CORE_H__ */
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define RC5T583_MAX_REGS 0xF8
|
||||
|
||||
/* Maximum number of main interrupts */
|
||||
#define MAX_MAIN_INTERRUPT 5
|
||||
#define RC5T583_MAX_GPEDGE_REG 2
|
||||
@ -169,6 +167,9 @@
|
||||
#define RC5T583_RTC_AY_MONTH 0xF3
|
||||
#define RC5T583_RTC_AY_YEAR 0xF4
|
||||
|
||||
#define RC5T583_MAX_REG 0xF7
|
||||
#define RC5T583_NUM_REGS (RC5T583_MAX_REG + 1)
|
||||
|
||||
/* RICOH_RC5T583 IRQ definitions */
|
||||
enum {
|
||||
RC5T583_IRQ_ONKEY,
|
||||
|
@ -29,24 +29,24 @@ extern struct regmap *syscon_regmap_lookup_by_phandle(
|
||||
#else
|
||||
static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct regmap *syscon_regmap_lookup_by_pdevname(const char *s)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct regmap *syscon_regmap_lookup_by_phandle(
|
||||
struct device_node *np,
|
||||
const char *property)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -422,6 +422,7 @@
|
||||
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26)
|
||||
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26)
|
||||
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26)
|
||||
#define IMX6SX_GPR5_PCIE_BTNRST_RESET BIT(19)
|
||||
#define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4)
|
||||
#define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4)
|
||||
#define IMX6SX_GPR5_CSI1_MUX_CTRL_CVD (0x1 << 4)
|
||||
@ -435,6 +436,10 @@
|
||||
#define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1)
|
||||
#define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1)
|
||||
|
||||
#define IMX6SX_GPR12_PCIE_TEST_POWERDOWN BIT(30)
|
||||
#define IMX6SX_GPR12_PCIE_RX_EQ_MASK (0x7 << 0)
|
||||
#define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)
|
||||
|
||||
/* For imx6ul iomux gpr register field define */
|
||||
#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17)
|
||||
#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18)
|
||||
|
117
include/linux/mfd/tps65086.h
Normal file
117
include/linux/mfd/tps65086.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Andrew F. Davis <afd@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether expressed or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License version 2 for more details.
|
||||
*
|
||||
* Based on the TPS65912 driver
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_TPS65086_H
|
||||
#define __LINUX_MFD_TPS65086_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* List of registers for TPS65086 */
|
||||
#define TPS65086_DEVICEID 0x01
|
||||
#define TPS65086_IRQ 0x02
|
||||
#define TPS65086_IRQ_MASK 0x03
|
||||
#define TPS65086_PMICSTAT 0x04
|
||||
#define TPS65086_SHUTDNSRC 0x05
|
||||
#define TPS65086_BUCK1CTRL 0x20
|
||||
#define TPS65086_BUCK2CTRL 0x21
|
||||
#define TPS65086_BUCK3DECAY 0x22
|
||||
#define TPS65086_BUCK3VID 0x23
|
||||
#define TPS65086_BUCK3SLPCTRL 0x24
|
||||
#define TPS65086_BUCK4CTRL 0x25
|
||||
#define TPS65086_BUCK5CTRL 0x26
|
||||
#define TPS65086_BUCK6CTRL 0x27
|
||||
#define TPS65086_LDOA2CTRL 0x28
|
||||
#define TPS65086_LDOA3CTRL 0x29
|
||||
#define TPS65086_DISCHCTRL1 0x40
|
||||
#define TPS65086_DISCHCTRL2 0x41
|
||||
#define TPS65086_DISCHCTRL3 0x42
|
||||
#define TPS65086_PG_DELAY1 0x43
|
||||
#define TPS65086_FORCESHUTDN 0x91
|
||||
#define TPS65086_BUCK1SLPCTRL 0x92
|
||||
#define TPS65086_BUCK2SLPCTRL 0x93
|
||||
#define TPS65086_BUCK4VID 0x94
|
||||
#define TPS65086_BUCK4SLPVID 0x95
|
||||
#define TPS65086_BUCK5VID 0x96
|
||||
#define TPS65086_BUCK5SLPVID 0x97
|
||||
#define TPS65086_BUCK6VID 0x98
|
||||
#define TPS65086_BUCK6SLPVID 0x99
|
||||
#define TPS65086_LDOA2VID 0x9A
|
||||
#define TPS65086_LDOA3VID 0x9B
|
||||
#define TPS65086_BUCK123CTRL 0x9C
|
||||
#define TPS65086_PG_DELAY2 0x9D
|
||||
#define TPS65086_PIN_EN_MASK1 0x9E
|
||||
#define TPS65086_PIN_EN_MASK2 0x9F
|
||||
#define TPS65086_SWVTT_EN 0x9F
|
||||
#define TPS65086_PIN_EN_OVR1 0xA0
|
||||
#define TPS65086_PIN_EN_OVR2 0xA1
|
||||
#define TPS65086_GPOCTRL 0xA1
|
||||
#define TPS65086_PWR_FAULT_MASK1 0xA2
|
||||
#define TPS65086_PWR_FAULT_MASK2 0xA3
|
||||
#define TPS65086_GPO1PG_CTRL1 0xA4
|
||||
#define TPS65086_GPO1PG_CTRL2 0xA5
|
||||
#define TPS65086_GPO4PG_CTRL1 0xA6
|
||||
#define TPS65086_GPO4PG_CTRL2 0xA7
|
||||
#define TPS65086_GPO2PG_CTRL1 0xA8
|
||||
#define TPS65086_GPO2PG_CTRL2 0xA9
|
||||
#define TPS65086_GPO3PG_CTRL1 0xAA
|
||||
#define TPS65086_GPO3PG_CTRL2 0xAB
|
||||
#define TPS65086_LDOA1CTRL 0xAE
|
||||
#define TPS65086_PG_STATUS1 0xB0
|
||||
#define TPS65086_PG_STATUS2 0xB1
|
||||
#define TPS65086_PWR_FAULT_STATUS1 0xB2
|
||||
#define TPS65086_PWR_FAULT_STATUS2 0xB3
|
||||
#define TPS65086_TEMPCRIT 0xB4
|
||||
#define TPS65086_TEMPHOT 0xB5
|
||||
#define TPS65086_OC_STATUS 0xB6
|
||||
|
||||
/* IRQ Register field definitions */
|
||||
#define TPS65086_IRQ_DIETEMP_MASK BIT(0)
|
||||
#define TPS65086_IRQ_SHUTDN_MASK BIT(3)
|
||||
#define TPS65086_IRQ_FAULT_MASK BIT(7)
|
||||
|
||||
/* DEVICEID Register field definitions */
|
||||
#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
|
||||
#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
|
||||
#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
|
||||
|
||||
/* VID Masks */
|
||||
#define BUCK_VID_MASK GENMASK(7, 1)
|
||||
#define VDOA1_VID_MASK GENMASK(4, 1)
|
||||
#define VDOA23_VID_MASK GENMASK(3, 0)
|
||||
|
||||
/* Define the TPS65086 IRQ numbers */
|
||||
enum tps65086_irqs {
|
||||
TPS65086_IRQ_DIETEMP,
|
||||
TPS65086_IRQ_SHUTDN,
|
||||
TPS65086_IRQ_FAULT,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tps65086 - state holder for the tps65086 driver
|
||||
*
|
||||
* Device data may be used to access the TPS65086 chip
|
||||
*/
|
||||
struct tps65086 {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
/* IRQ Data */
|
||||
int irq;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_TPS65086_H */
|
@ -77,6 +77,11 @@ enum {
|
||||
#define TPS65090_REG_CG_CTRL5 0x09
|
||||
#define TPS65090_REG_CG_STATUS1 0x0a
|
||||
#define TPS65090_REG_CG_STATUS2 0x0b
|
||||
#define TPS65090_REG_AD_OUT1 0x17
|
||||
#define TPS65090_REG_AD_OUT2 0x18
|
||||
|
||||
#define TPS65090_MAX_REG TPS65090_REG_AD_OUT2
|
||||
#define TPS65090_NUM_REGS (TPS65090_MAX_REG + 1)
|
||||
|
||||
struct tps65090 {
|
||||
struct device *dev;
|
||||
|
Loading…
Reference in New Issue
Block a user