Commit 532c2b92 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mfd-next-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Drivers:
   - Add Cirrus Logic Madera Codec (CS47L35, CS47L85 and CS47L90/91) driver
   - Add ChromeOS EC CEC driver
   - Add ROHM BD71837 PMIC driver

  New Device Support:
   - Add support for Dialog Semi DA9063L PMIC variant to DA9063
   - Add support for Intel Ice Lake to Intel-PLSS-PCI
   - Add support for X-Powers AXP806 to AXP20x

  New Functionality:
   - Add support for USB Charging to the ChromeOS Embedded Controller
   - Add support for HDMI CEC to the ChromeOS Embedded Controller
   - Add support for HDMI CEC to Intel HDMI
   - Add support for accessory detection to Madera devices
   - Allow individual pins to be configured via DT' wlf,csnaddr-pd
   - Provide legacy platform specific EEPROM/Watchdog commands; rave-sp

  Fix-upsL
   - Trivial renaming/spelling fixes; cros_ec, da9063-*
   - Convert to Managed Resources (devm_*); da9063-*, ti_am335x_tscadc
   - Transition to helper macros/functions; da9063-*
   - Constify; kempld-core
   - Improve error path/messages; wm8994-core
   - Disable IRQs locally instead of relying on USB subsystem; dln2
   - Remove unused code; rave-sp
   - New exports; sec-core

  Bug Fixes:
   - Fix possible false I2C transaction error; arizona-core
   - Fix declared memory area size; hi655x-pmic
   - Fix checksum type; rave-sp
   - Fix incorrect default serial port configuration: rave-sp
   - Fix incorrect coherent DMA mask for sub-devices; sm501"

* tag 'mfd-next-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (60 commits)
  mfd: madera: Add register definitions for accessory detect
  mfd: sm501: Set coherent_dma_mask when creating subdevices
  mfd: bd71837: Devicetree bindings for ROHM BD71837 PMIC
  mfd: bd71837: Core driver for ROHM BD71837 PMIC
  media: platform: cros-ec-cec: Fix dependency on MFD_CROS_EC
  mfd: sec-core: Export OF module alias table
  mfd: as3722: Disable auto-power-on when AC OK
  mfd: axp20x: Support AXP806 in I2C mode
  mfd: axp20x: Add self-working mode support for AXP806
  dt-bindings: mfd: axp20x: Add "self-working" mode for AXP806
  mfd: wm8994: Allow to configure CS/ADDR Pulldown from dts
  mfd: wm8994: Allow to configure Speaker Mode Pullup from dts
  mfd: rave-sp: Emulate CMD_GET_STATUS on device that don't support it
  mfd: rave-sp: Add legacy watchdog ping command translation
  mfd: rave-sp: Add legacy EEPROM access command translation
  mfd: rave-sp: Initialize flow control and parity of the port
  mfd: rave-sp: Fix incorrectly specified checksum type
  mfd: rave-sp: Remove unused defines
  mfd: hi655x: Fix regmap area declared size for hi655x
  mfd: ti_am335x_tscadc: Fix struct clk memory leak
  ...
parents 8786583d d2c9281c
......@@ -20,6 +20,8 @@ Optional properties:
- ams,enable-internal-i2c-pullup: Boolean property, to enable internal pullup on
i2c scl/sda pins. Missing this will disable internal pullup on i2c
scl/sda lines.
- ams,enable-ac-ok-power-on: Boolean property, to enable exit out of power off
mode with AC_OK pin (pin enabled in power off mode).
Optional submodule and their properties:
=======================================
......
......@@ -44,8 +44,11 @@ Optional properties:
board is driving OTG VBus or not.
(axp221 / axp223 / axp803/ axp813 only)
- x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is
wired for master mode. The default is slave mode.
- x-powers,self-working-mode and
x-powers,master-mode: Boolean (axp806 only). Set either of these when the
PMIC is wired for self-working mode or master mode.
If neither is set then slave mode is assumed.
This corresponds to how the MODESET pin is wired.
- <input>-supply: a phandle to the regulator supply node. May be omitted if
inputs are unregulated, such as using the IPSOUT output
......
Cirrus Logic Madera class audio codecs Multi-Functional Device
These devices are audio SoCs with extensive digital capabilities and a range
of analogue I/O.
See also the child driver bindings in:
bindings/pinctrl/cirrus,madera-pinctrl.txt
bindings/regulator/arizona-regulator.txt
bindings/sound/madera.txt
Required properties:
- compatible : One of the following chip-specific strings:
"cirrus,cs47l35"
"cirrus,cs47l85"
"cirrus,cs47l90"
"cirrus,cs47l91"
"cirrus,wm1840"
- reg : I2C slave address when connected using I2C, chip select number when
using SPI.
- DCVDD-supply : Power supply for the device as defined in
bindings/regulator/regulator.txt
Mandatory on CS47L35, CS47L90, CS47L91
Optional on CS47L85, WM1840
- AVDD-supply, DBVDD1-supply, DBVDD2-supply, CPVDD1-supply, CPVDD2-supply :
Power supplies for the device
- DBVDD3-supply, DBVDD4-supply : Power supplies for the device
(CS47L85, CS47L90, CS47L91, WM1840)
- SPKVDDL-supply, SPKVDDR-supply : Power supplies for the device
(CS47L85, WM1840)
- SPKVDD-supply : Power supply for the device
(CS47L35)
- interrupt-controller : Indicates that this device is an interrupt controller
- #interrupt-cells: the number of cells to describe an IRQ, must be 2.
The first cell is the IRQ number.
The second cell is the flags, encoded as the trigger masks from
bindings/interrupt-controller/interrupts.txt
- gpio-controller : Indicates this device is a GPIO controller.
- #gpio-cells : Must be 2. The first cell is the pin number. The second cell
is reserved for future use and must be zero
- interrupt-parent : The parent interrupt controller.
- interrupts : The interrupt line the /IRQ signal for the device is
connected to.
Optional properties:
- MICVDD-supply : Power supply, only need to be specified if
powered externally
- reset-gpios : One entry specifying the GPIO controlling /RESET.
As defined in bindings/gpio.txt.
Although optional, it is strongly recommended to use a hardware reset
- MICBIASx : Initial data for the MICBIAS regulators, as covered in
Documentation/devicetree/bindings/regulator/regulator.txt.
One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
(all codecs)
One for each output pin (MICBIAS1A, MIBCIAS1B, MICBIAS2A, ...)
(all except CS47L85, WM1840)
The following following additional property is supported for the generator
nodes:
- cirrus,ext-cap : Set to 1 if the MICBIAS has external decoupling
capacitors attached.
Optional child nodes:
micvdd : Node containing initialization data for the micvdd regulator
See bindings/regulator/arizona-regulator.txt
ldo1 : Node containing initialization data for the LDO1 regulator
See bindings/regulator/arizona-regulator.txt
(cs47l85, wm1840)
Example:
cs47l85@0 {
compatible = "cirrus,cs47l85";
reg = <0>;
reset-gpios = <&gpio 0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <&host_irq1>;
interrupt-parent = <&gic>;
gpio-controller;
#gpio-cells = <2>;
};
* ROHM BD71837 Power Management Integrated Circuit bindings
BD71837MWV is a programmable Power Management IC for powering single-core,
dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is optimized for
low BOM cost and compact solution footprint. It integrates 8 Buck
egulators and 7 LDOs to provide all the power rails required by the SoC and
the commonly used peripherals.
Datasheet for PMIC is available at:
https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
Required properties:
- compatible : Should be "rohm,bd71837".
- reg : I2C slave address.
- interrupt-parent : Phandle to the parent interrupt controller.
- interrupts : The interrupt line the device is connected to.
- clocks : The parent clock connected to PMIC. If this is missing
32768 KHz clock is assumed.
- #clock-cells : Should be 0.
- regulators: : List of child nodes that specify the regulators.
Please see ../regulator/rohm,bd71837-regulator.txt
Optional properties:
- clock-output-names : Should contain name for output clock.
Example:
/* external oscillator node */
osc: oscillator {
compatible = "fixed-clock";
#clock-cells = <1>;
clock-frequency = <32768>;
clock-output-names = "osc";
};
pmic: pmic@4b {
compatible = "rohm,bd71837";
reg = <0x4b>;
interrupt-parent = <&gpio1>;
interrupts = <29 GPIO_ACTIVE_LOW>;
interrupt-names = "irq";
#clock-cells = <0>;
clocks = <&osc 0>;
clock-output-names = "bd71837-32k-out";
regulators {
buck1: BUCK1 {
regulator-name = "buck1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-boot-on;
regulator-ramp-delay = <1250>;
};
};
};
/* Clock consumer node */
rtc@0 {
compatible = "company,my-rtc";
clock-names = "my-clock";
clocks = <&pmic>;
};
......@@ -22,7 +22,7 @@ Required properties:
The valid regulator-compatible values are:
tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1,
vaux2, vaux33, vmmc, vbb
tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5,
tps65911: vrtc, vio, vdd1, vdd2, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5,
ldo6, ldo7, ldo8
- xxx-supply: Input voltage supply regulator.
......
Cirrus Logic Madera class audio codecs pinctrl driver
The Cirrus Logic Madera codecs provide a number of GPIO functions for
interfacing to external hardware and to provide logic outputs to other devices.
Certain groups of GPIO pins also have an alternate function, normally as an
audio interface.
The set of available GPIOs, functions and alternate function groups differs
between codecs so refer to the datasheet for the codec for further information
on what is supported on that device.
The properties for this driver exist within the parent MFD driver node.
See also
the core bindings for the parent MFD driver:
Documentation/devicetree/bindings/mfd/madera.txt
the generic pinmix bindings:
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Required properties of parent mfd node:
- pinctrl-names : must be "default"
- pinctrl-0 : a phandle to the node containing the subnodes containing default
configurations
Required subnodes:
One subnode is required to contain the default settings. It contains an
arbitrary number of configuration subnodes, one for each group or pin
configuration you want to apply as a default.
Required properties of configuration subnodes:
- groups : name of one pin group to configure. One of:
aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
dmic4, dmic5, dmic6,
gpio1, gpio2, ..., gpio40
The gpioN groups select the single pin of this name for configuration
Optional properties of configuration subnodes:
Any configuration option not explicitly listed in the dts will be left at
chip default setting.
- function : name of function to assign to this group. One of:
aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
dmic3, dmic4, dmic5, dmic6,
io, dsp-gpio, irq1, irq2,
fll1-clk, fll1-lock, fll2-clk, fll2-lock, fll3-clk, fll3-lock,
fllao-clk, fllao-lock,
opclk, opclk-async, pwm1, pwm2, spdif,
asrc1-in1-lock, asrc1-in2-lock, asrc2-in1-lock, asrc2-in2-lock,
spkl-short-circuit, spkr-short-circuit, spk-shutdown,
spk-overheat-shutdown, spk-overheat-warn,
timer1-sts, timer2-sts, timer3-sts, timer4-sts, timer5-sts, timer6-sts,
timer7-sts, timer8-sts,
log1-fifo-ne, log2-fifo-ne, log3-fifo-ne, log4-fifo-ne, log5-fifo-ne,
log6-fifo-ne, log7-fifo-ne, log8-fifo-ne,
- bias-disable : disable pull-up and pull-down
- bias-bus-hold : enable buskeeper
- bias-pull-up : output is pulled-up
- bias-pull-down : output is pulled-down
- drive-push-pull : CMOS output
- drive-open-drain : open-drain output
- drive-strength : drive strength in mA. Valid values are 4 or 8
- input-schmitt-enable : enable schmitt-trigger mode
- input-schmitt-disable : disable schmitt-trigger mode
- input-debounce : A value of 0 disables debounce, a value !=0 enables
debounce
- output-low : set the pin to output mode with low level
- output-high : set the pin to output mode with high level
Example:
cs47l85@0 {
compatible = "cirrus,cs47l85";
pinctrl-names = "default";
pinctrl-0 = <&cs47l85_defaults>;
cs47l85_defaults: cs47l85-gpio-defaults {
aif1 {
groups = "aif1";
function = "aif1";
bias-bus-hold;
};
aif2 {
groups = "aif2";
function = "aif2";
bias-bus-hold;
};
opclk {
groups = "gpio1";
function = "opclk";
bias-pull-up;
drive-strength = <8>;
};
};
};
......@@ -3562,6 +3562,22 @@ M: Christian Benvenuti <benve@cisco.com>
S: Supported
F: drivers/infiniband/hw/usnic/
CIRRUS LOGIC MADERA CODEC DRIVERS
M: Charles Keepax <ckeepax@opensource.cirrus.com>
M: Richard Fitzgerald <rf@opensource.cirrus.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: patches@opensource.cirrus.com
T: git https://github.com/CirrusLogic/linux-drivers.git
W: https://github.com/CirrusLogic/linux-drivers/wiki
S: Supported
F: Documentation/devicetree/bindings/mfd/madera.txt
F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
F: include/linux/mfd/madera/*
F: drivers/gpio/gpio-madera*
F: drivers/mfd/madera*
F: drivers/mfd/cs47l*
F: drivers/pinctrl/cirrus/*
CLANG-FORMAT FILE
M: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
S: Maintained
......
......@@ -155,8 +155,8 @@ CONFIG_THERMAL_EMULATION=y
CONFIG_WATCHDOG=y
CONFIG_S3C2410_WATCHDOG=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_MFD_CROS_EC_SPI=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_SPI=y
CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
......
......@@ -490,8 +490,8 @@ CONFIG_MFD_AC100=y
CONFIG_MFD_AXP20X_I2C=y
CONFIG_MFD_AXP20X_RSB=y
CONFIG_MFD_CROS_EC=m
CONFIG_MFD_CROS_EC_I2C=m
CONFIG_MFD_CROS_EC_SPI=m
CONFIG_CROS_EC_I2C=m
CONFIG_CROS_EC_SPI=m
CONFIG_MFD_DA9063=m
CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
......
......@@ -398,8 +398,8 @@ CONFIG_MFD_AS3711=y
CONFIG_MFD_BCM590XX=m
CONFIG_MFD_AXP20X=y
CONFIG_MFD_CROS_EC=m
CONFIG_MFD_CROS_EC_I2C=m
CONFIG_MFD_CROS_EC_SPI=m
CONFIG_CROS_EC_I2C=m
CONFIG_CROS_EC_SPI=m
CONFIG_MFD_ASIC3=y
CONFIG_PMIC_DA903X=y
CONFIG_HTC_EGPIO=y
......
......@@ -373,8 +373,8 @@ CONFIG_UNIPHIER_WATCHDOG=y
CONFIG_BCM2835_WDT=y
CONFIG_MFD_AXP20X_RSB=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_MFD_CROS_EC_SPI=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_SPI=y
CONFIG_MFD_CROS_EC_CHARDEV=m
CONFIG_MFD_EXYNOS_LPASS=m
CONFIG_MFD_HI6421_PMIC=y
......
......@@ -1049,6 +1049,12 @@ config GPIO_LP87565
This driver can also be built as a module. If so, the module will be
called gpio-lp87565.
config GPIO_MADERA
tristate "Cirrus Logic Madera class codecs"
depends on PINCTRL_MADERA
help
Support for GPIOs on Cirrus Logic Madera class codecs.
config GPIO_MAX77620
tristate "GPIO support for PMIC MAX77620 and MAX20024"
depends on MFD_MAX77620
......
......@@ -71,6 +71,7 @@ obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o
obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o
obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* GPIO support for Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/gpio/driver.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/madera/core.h>
#include <linux/mfd/madera/pdata.h>
#include <linux/mfd/madera/registers.h>
struct madera_gpio {
struct madera *madera;
/* storage space for the gpio_chip we're using */
struct gpio_chip gpio_chip;
};
static int madera_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
struct madera *madera = madera_gpio->madera;
unsigned int reg_offset = 2 * offset;
unsigned int val;
int ret;
ret = regmap_read(madera->regmap, MADERA_GPIO1_CTRL_2 + reg_offset,
&val);
if (ret < 0)
return ret;
return !!(val & MADERA_GP1_DIR_MASK);
}
static int madera_gpio_direction_in(struct gpio_chip *chip, unsigned int offset)
{
struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
struct madera *madera = madera_gpio->madera;
unsigned int reg_offset = 2 * offset;
return regmap_update_bits(madera->regmap,
MADERA_GPIO1_CTRL_2 + reg_offset,
MADERA_GP1_DIR_MASK, MADERA_GP1_DIR);
}
static int madera_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
struct madera *madera = madera_gpio->madera;
unsigned int reg_offset = 2 * offset;
unsigned int val;
int ret;
ret = regmap_read(madera->regmap, MADERA_GPIO1_CTRL_1 + reg_offset,
&val);
if (ret < 0)
return ret;
return !!(val & MADERA_GP1_LVL_MASK);
}
static int madera_gpio_direction_out(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
struct madera *madera = madera_gpio->madera;
unsigned int reg_offset = 2 * offset;
unsigned int reg_val = value ? MADERA_GP1_LVL : 0;
int ret;
ret = regmap_update_bits(madera->regmap,
MADERA_GPIO1_CTRL_2 + reg_offset,
MADERA_GP1_DIR_MASK, 0);
if (ret < 0)
return ret;
return regmap_update_bits(madera->regmap,
MADERA_GPIO1_CTRL_1 + reg_offset,
MADERA_GP1_LVL_MASK, reg_val);
}
static void madera_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
struct madera *madera = madera_gpio->madera;
unsigned int reg_offset = 2 * offset;
unsigned int reg_val = value ? MADERA_GP1_LVL : 0;
int ret;
ret = regmap_update_bits(madera->regmap,
MADERA_GPIO1_CTRL_1 + reg_offset,
MADERA_GP1_LVL_MASK, reg_val);
/* set() doesn't return an error so log a warning */
if (ret)
dev_warn(madera->dev, "Failed to write to 0x%x (%d)\n",
MADERA_GPIO1_CTRL_1 + reg_offset, ret);
}
static struct gpio_chip madera_gpio_chip = {
.label = "madera",
.owner = THIS_MODULE,
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.get_direction = madera_gpio_get_direction,
.direction_input = madera_gpio_direction_in,
.get = madera_gpio_get,
.direction_output = madera_gpio_direction_out,
.set = madera_gpio_set,
.set_config = gpiochip_generic_config,
.can_sleep = true,
};
static int madera_gpio_probe(struct platform_device *pdev)
{
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
struct madera_pdata *pdata = dev_get_platdata(madera->dev);
struct madera_gpio *madera_gpio;
int ret;
madera_gpio = devm_kzalloc(&pdev->dev, sizeof(*madera_gpio),
GFP_KERNEL);
if (!madera_gpio)
return -ENOMEM;
madera_gpio->madera = madera;
/* Construct suitable gpio_chip from the template in madera_gpio_chip */
madera_gpio->gpio_chip = madera_gpio_chip;
madera_gpio->gpio_chip.parent = pdev->dev.parent;
switch (madera->type) {
case CS47L35:
madera_gpio->gpio_chip.ngpio = CS47L35_NUM_GPIOS;
break;
case CS47L85:
case WM1840:
madera_gpio->gpio_chip.ngpio = CS47L85_NUM_GPIOS;
break;
case CS47L90:
case CS47L91:
madera_gpio->gpio_chip.ngpio = CS47L90_NUM_GPIOS;
break;
default:
dev_err(&pdev->dev, "Unknown chip variant %d\n", madera->type);
return -EINVAL;
}
/* We want to be usable on systems that don't use devicetree or acpi */
if (pdata && pdata->gpio_base)
madera_gpio->gpio_chip.base = pdata->gpio_base;
else
madera_gpio->gpio_chip.base = -1;
ret = devm_gpiochip_add_data(&pdev->dev,
&madera_gpio->gpio_chip,
madera_gpio);
if (ret < 0) {
dev_dbg(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
/*
* This is part of a composite MFD device which can only be used with
* the corresponding pinctrl driver. On all supported silicon the GPIO
* to pinctrl mapping is fixed in the silicon, so we register it
* explicitly instead of requiring a redundant gpio-ranges in the
* devicetree.
* In any case we also want to work on systems that don't use devicetree
* or acpi.
*/
ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
0, 0, madera_gpio->gpio_chip.ngpio);
if (ret) {
dev_dbg(&pdev->dev, "Failed to add pin range (%d)\n", ret);
return ret;
}
return 0;
}
static struct platform_driver madera_gpio_driver = {
.driver = {
.name = "madera-gpio",
},
.probe = madera_gpio_probe,
};
module_platform_driver(madera_gpio_driver);
MODULE_SOFTDEP("pre: pinctrl-madera");
MODULE_DESCRIPTION("GPIO interface for Madera codecs");
MODULE_AUTHOR("Nariman Poushin <nariman@opensource.cirrus.com>");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:madera-gpio");
......@@ -24,6 +24,7 @@ config DRM_I915
select IOSF_MBI
select CRC32
select SND_HDA_I915 if SND_HDA_CORE
select CEC_CORE if CEC_NOTIFIER
help
Choose this option if you have a system that has "Intel Graphics
Media Accelerator" or "HD Graphics" integrated graphics,
......
......@@ -126,6 +126,30 @@ enum port {
#define port_name(p) ((p) + 'A')
/*
* Ports identifier referenced from other drivers.
* Expected to remain stable over time
*/
static inline const char *port_identifier(enum port port)
{
switch (port) {
case PORT_A:
return "Port A";
case PORT_B:
return "Port B";
case PORT_C:
return "Port C";
case PORT_D:
return "Port D";
case PORT_E:
return "Port E";
case PORT_F:
return "Port F";
default:
return "<invalid>";
}
}
enum tc_port {
PORT_TC_NONE = -1,
......
......@@ -39,6 +39,7 @@
#include <drm/drm_dp_mst_helper.h>
#include <drm/drm_rect.h>
#include <drm/drm_atomic.h>
#include <media/cec-notifier.h>
/**
* __wait_for - magic wait macro
......@@ -1016,6 +1017,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
struct cec_notifier *cec_notifier;
};
struct intel_dp_mst_encoder;
......
......@@ -1899,6 +1899,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, edid);
return connected;
}
......@@ -1907,6 +1909,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
{
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
......@@ -1922,6 +1925,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
if (status != connector_status_connected)
cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
return status;
}
......@@ -2062,6 +2068,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder,
static void intel_hdmi_destroy(struct drm_connector *connector)
{
if (intel_attached_hdmi(connector)->cec_notifier)
cec_notifier_put(intel_attached_hdmi(connector)->cec_notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
......@@ -2382,6 +2390,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
intel_hdmi->cec_notifier = cec_notifier_get_conn(dev->dev,
port_identifier(port));
if (!intel_hdmi->cec_notifier)
DRM_DEBUG_KMS("CEC notifier get failed\n");
}
void intel_hdmi_init(struct drm_i915_private *dev_priv,
......
......@@ -721,7 +721,7 @@ config KEYBOARD_CROS_EC
help
Say Y here to enable the matrix keyboard used by ChromeOS devices
and implemented on the ChromeOS EC. You must enable one bus option
(MFD_CROS_EC_I2C or MFD_CROS_EC_SPI) to use this.
(CROS_EC_I2C or CROS_EC_SPI) to use this.
To compile this driver as a module, choose M here: the
module will be called cros_ec_keyb.
......
......@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
......@@ -30,13 +31,14 @@ struct cec_notifier {
static LIST_HEAD(cec_notifiers);
static DEFINE_MUTEX(cec_notifiers_lock);
struct cec_notifier *cec_notifier_get(struct device *dev)
struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)
{
struct cec_notifier *n;
mutex_lock(&cec_notifiers_lock);
list_for_each_entry(n, &cec_notifiers, head) {
if (n->dev == dev) {
if (n->dev == dev &&
(!conn || !strcmp(n->conn, conn))) {
kref_get(&n->kref);
mutex_unlock(&cec_notifiers_lock);
return n;
......@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
if (conn)
n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(&n->lock);
kref_init(&n->kref);
......@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(&cec_notifiers_lock);
return n;
}
EXPORT_SYMBOL_GPL(cec_notifier_get);
EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
static void cec_notifier_release(struct kref *kref)
{
......@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
list_del(&n->head);
kfree(n->conn);
kfree(n);
}
......
......@@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
if CEC_PLATFORM_DRIVERS
config VIDEO_CROS_EC_CEC
tristate "ChromeOS EC CEC driver"
depends on MFD_CROS_EC
select CEC_CORE
select CEC_NOTIFIER
---help---
If you say yes here you will get support for the
ChromeOS Embedded Controller's CEC.
The CEC bus is present in the HDMI connector and enables communication
between compatible devices.
config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
......
......@@ -94,3 +94,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss/
obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
obj-y += meson/
obj-y += cros-ec-cec/
obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
// SPDX-License-Identifier: GPL-2.0+
/*
* CEC driver for ChromeOS Embedded Controller
*
* Copyright (c) 2018 BayLibre, SAS
* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dmi.h>
#include <linux/pci.h>
#include <linux/cec.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <media/cec.h>
#include <media/cec-notifier.h>
#include <linux/mfd/cros_ec.h>
#include <linux/mfd/cros_ec_commands.h>
#define DRV_NAME "cros-ec-cec"
/**
* struct cros_ec_cec - Driver data for EC CEC
*
* @cros_ec: Pointer to EC device
* @notifier: Notifier info for responding to EC events
* @adap: CEC adapter
* @notify: CEC notifier pointer
* @rx_msg: storage for a received message
*/
struct cros_ec_cec {
struct cros_ec_device *cros_ec;
struct notifier_block notifier;
struct cec_adapter *adap;
struct cec_notifier *notify;
struct cec_msg rx_msg;
};
static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
{
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
uint8_t *cec_message = cros_ec->event_data.data.cec_message;
unsigned int len = cros_ec->event_size;
cros_ec_cec->rx_msg.len = len;
memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg);
}
static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
{
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
uint32_t events = cros_ec->event_data.data.cec_events;
if (events & EC_MKBP_CEC_SEND_OK)
cec_transmit_attempt_done(cros_ec_cec->adap,
CEC_TX_STATUS_OK);
/* FW takes care of all retries, tell core to avoid more retries */
if (events & EC_MKBP_CEC_SEND_FAILED)
cec_transmit_attempt_done(cros_ec_cec->adap,
CEC_TX_STATUS_MAX_RETRIES |
CEC_TX_STATUS_NACK);
}
static int cros_ec_cec_event(struct notifier_block *nb,
unsigned long queued_during_suspend,
void *_notify)
{
struct cros_ec_cec *cros_ec_cec;
struct cros_ec_device *cros_ec;
cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier);
cros_ec = cros_ec_cec->cros_ec;
if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_EVENT) {
handle_cec_event(cros_ec_cec);
return NOTIFY_OK;
}
if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_MESSAGE) {
handle_cec_message(cros_ec_cec);
return NOTIFY_OK;
}
return NOTIFY_DONE;
}
static int cros_ec_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
{
struct cros_ec_cec *cros_ec_cec = adap->priv;
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
struct {
struct cros_ec_command msg;
struct ec_params_cec_set data;
} __packed msg = {};
int ret;
msg.msg.command = EC_CMD_CEC_SET;
msg.msg.outsize = sizeof(msg.data);
msg.data.cmd = CEC_CMD_LOGICAL_ADDRESS;
msg.data.val = logical_addr;
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) {
dev_err(cros_ec->dev,
"error setting CEC logical address on EC: %d\n", ret);
return ret;
}
return 0;
}
static int cros_ec_cec_transmit(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *cec_msg)
{
struct cros_ec_cec *cros_ec_cec = adap->priv;
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
struct {
struct cros_ec_command msg;
struct ec_params_cec_write data;
} __packed msg = {};
int ret;
msg.msg.command = EC_CMD_CEC_WRITE_MSG;
msg.msg.outsize = cec_msg->len;
memcpy(msg.data.msg, cec_msg->msg, cec_msg->len);
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) {
dev_err(cros_ec->dev,
"error writing CEC msg on EC: %d\n", ret);
return ret;
}
return 0;
}
static int cros_ec_cec_adap_enable(struct cec_adapter *adap, bool enable)
{
struct cros_ec_cec *cros_ec_cec = adap->priv;
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
struct {
struct cros_ec_command msg;
struct ec_params_cec_set data;
} __packed msg = {};
int ret;
msg.msg.command = EC_CMD_CEC_SET;
msg.msg.outsize = sizeof(msg.data);
msg.data.cmd = CEC_CMD_ENABLE;
msg.data.val = enable;
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) {
dev_err(cros_ec->dev,
"error %sabling CEC on EC: %d\n",
(enable ? "en" : "dis"), ret);
return ret;
}
return 0;
}
static const struct cec_adap_ops cros_ec_cec_ops = {
.adap_enable = cros_ec_cec_adap_enable,
.adap_log_addr = cros_ec_cec_set_log_addr,
.adap_transmit = cros_ec_cec_transmit,
};
#ifdef CONFIG_PM_SLEEP
static int cros_ec_cec_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
if (device_may_wakeup(dev))
enable_irq_wake(cros_ec_cec->cros_ec->irq);
return 0;
}
static int cros_ec_cec_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
if (device_may_wakeup(dev))
disable_irq_wake(cros_ec_cec->cros_ec->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops,
cros_ec_cec_suspend, cros_ec_cec_resume);
#if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
/*
* The Firmware only handles a single CEC interface tied to a single HDMI
* connector we specify along with the DRM device name handling the HDMI output
*/
struct cec_dmi_match {
char *sys_vendor;
char *product_name;
char *devname;
char *conn;
};
static const struct cec_dmi_match cec_dmi_match_table[] = {
/* Google Fizz */
{ "Google", "Fizz", "0000:00:02.0", "Port B" },
};
static int cros_ec_cec_get_notifier(struct device *dev,
struct cec_notifier **notify)
{
int i;
for (i = 0 ; i < ARRAY_SIZE(cec_dmi_match_table) ; ++i) {
const struct cec_dmi_match *m = &cec_dmi_match_table[i];
if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) &&
dmi_match(DMI_PRODUCT_NAME, m->product_name)) {
struct device *d;
/* Find the device, bail out if not yet registered */
d = bus_find_device_by_name(&pci_bus_type, NULL,
m->devname);
if (!d)
return -EPROBE_DEFER;
*notify = cec_notifier_get_conn(d, m->conn);
return 0;
}
}
/* Hardware support must be added in the cec_dmi_match_table */
dev_warn(dev, "CEC notifier not configured for this hardware\n");
return -ENODEV;
}
#else
static int cros_ec_cec_get_notifier(struct device *dev,
struct cec_notifier **notify)
{
return -ENODEV;
}
#endif
static int cros_ec_cec_probe(struct platform_device *pdev)
{
struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
struct cros_ec_device *cros_ec = ec_dev->ec_dev;
struct cros_ec_cec *cros_ec_cec;
int ret;
cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec),
GFP_KERNEL);
if (!cros_ec_cec)
return -ENOMEM;
platform_set_drvdata(pdev, cros_ec_cec);
cros_ec_cec->cros_ec = cros_ec;
ret = cros_ec_cec_get_notifier(&pdev->dev, &cros_ec_cec->notify);
if (ret)
return ret;
ret = device_init_wakeup(&pdev->dev, 1);
if (ret) {
dev_err(&pdev->dev, "failed to initialize wakeup\n");
return ret;
}
cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,
DRV_NAME, CEC_CAP_DEFAULTS, 1);
if (IS_ERR(cros_ec_cec->adap))
return PTR_ERR(cros_ec_cec->adap);
/* Get CEC events from the EC. */
cros_ec_cec->notifier.notifier_call = cros_ec_cec_event;
ret = blocking_notifier_chain_register(&cros_ec->event_notifier,
&cros_ec_cec->notifier);
if (ret) {
dev_err(&pdev->dev, "failed to register notifier\n");
cec_delete_adapter(cros_ec_cec->adap);
return ret;
}
ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev);
if (ret < 0) {
cec_delete_adapter(cros_ec_cec->adap);
return ret;
}
cec_register_cec_notifier(cros_ec_cec->adap, cros_ec_cec->notify);
return 0;
}
static int cros_ec_cec_remove(struct platform_device *pdev)
{
struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
int ret;
ret = blocking_notifier_chain_unregister(
&cros_ec_cec->cros_ec->event_notifier,
&cros_ec_cec->notifier);
if (ret) {
dev_err(dev, "failed to unregister notifier\n");
return ret;
}
cec_unregister_adapter(cros_ec_cec->adap);
if (cros_ec_cec->notify)
cec_notifier_put(cros_ec_cec->notify);
return 0;
}
static struct platform_driver cros_ec_cec_driver = {
.probe = cros_ec_cec_probe,
.remove = cros_ec_cec_remove,
.driver = {
.name = DRV_NAME,
.pm = &cros_ec_cec_pm_ops,
},
};
module_platform_driver(cros_ec_cec_driver);
MODULE_DESCRIPTION("CEC driver for ChromeOS ECs");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
......@@ -202,26 +202,6 @@ config MFD_CROS_EC
You also need to enable the driver for the bus you are using. The
protocol for talking to the EC is defined by the bus driver.
config MFD_CROS_EC_I2C
tristate "ChromeOS Embedded Controller (I2C)"
depends on MFD_CROS_EC && I2C
help
If you say Y here, you get support for talking to the ChromeOS
EC through an I2C bus. This uses a simple byte-level protocol with
a checksum. Failing accesses will be retried three times to
improve reliability.
config MFD_CROS_EC_SPI
tristate "ChromeOS Embedded Controller (SPI)"
depends on MFD_CROS_EC && SPI
---help---
If you say Y here, you get support for talking to the ChromeOS EC
through a SPI bus, using a byte-level protocol. Since the EC's
response time cannot be guaranteed, we support ignoring
'pre-amble' bytes before the response actually starts.
config MFD_CROS_EC_CHARDEV
tristate "Chrome OS Embedded Controller userspace device interface"
depends on MFD_CROS_EC
......@@ -232,6 +212,56 @@ config MFD_CROS_EC_CHARDEV
If you have a supported Chromebook, choose Y or M here.
The module will be called cros_ec_dev.
config MFD_MADERA
tristate "Cirrus Logic Madera codecs"
select MFD_CORE
select REGMAP
select REGMAP_IRQ
select MADERA_IRQ
select PINCTRL
select PINCTRL_MADERA
help
Support for the Cirrus Logic Madera platform audio codecs
config MFD_MADERA_I2C
tristate "Cirrus Logic Madera codecs with I2C"
depends on MFD_MADERA
depends on I2C
select REGMAP_I2C
help
Support for the Cirrus Logic Madera platform audio SoC
core functionality controlled via I2C.
config MFD_MADERA_SPI
tristate "Cirrus Logic Madera codecs with SPI"
depends on MFD_MADERA
depends on SPI_MASTER
select REGMAP_SPI
help
Support for the Cirrus Logic Madera platform audio SoC
core functionality controlled via SPI.
config MFD_CS47L35
bool "Cirrus Logic CS47L35"
select PINCTRL_CS47L35
depends on MFD_MADERA
help
Support for Cirrus Logic CS47L35 Smart Codec
config MFD_CS47L85
bool "Cirrus Logic CS47L85"
select PINCTRL_CS47L85
depends on MFD_MADERA
help
Support for Cirrus Logic CS47L85 Smart Codec
config MFD_CS47L90
bool "Cirrus Logic CS47L90/91"
select PINCTRL_CS47L90
depends on MFD_MADERA
help
Support for Cirrus Logic CS47L90 and CS47L91 Smart Codecs
config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
......@@ -1787,6 +1817,19 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
config MFD_ROHM_BD718XX
tristate "ROHM BD71837 Power Management IC"
depends on I2C=y
depends on OF
select REGMAP_I2C
select REGMAP_IRQ
select MFD_CORE
help
Select this option to get support for the ROHM BD71837
Power Management ICs. BD71837 is designed to power processors like
NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring
and emergency shut down as well as 32,768KHz clock output.
config MFD_STM32_LPTIMER
tristate "Support for STM32 Low-Power Timer"
depends on (ARCH_STM32 && OF) || COMPILE_TEST
......
......@@ -14,8 +14,6 @@ obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
cros_ec_core-objs := cros_ec.o
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
obj-$(CONFIG_MFD_CROS_EC_CHARDEV) += cros_ec_dev.o
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
......@@ -72,6 +70,20 @@ wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_MFD_WM8994) += wm8994.o
obj-$(CONFIG_MFD_WM97xx) += wm97xx-core.o
madera-objs := madera-core.o
ifeq ($(CONFIG_MFD_CS47L35),y)
madera-objs += cs47l35-tables.o
endif
ifeq ($(CONFIG_MFD_CS47L85),y)
madera-objs += cs47l85-tables.o
endif
ifeq ($(CONFIG_MFD_CS47L90),y)
madera-objs += cs47l90-tables.o
endif
obj-$(CONFIG_MFD_MADERA) += madera.o
obj-$(CONFIG_MFD_MADERA_I2C) += madera-i2c.o
obj-$(CONFIG_MFD_MADERA_SPI) += madera-spi.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_TPS6507X) += tps6507x.o
......@@ -227,4 +239,5 @@ obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
......@@ -24,6 +24,7 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/slab.h>
#include <linux/ktime.h>
#include <linux/platform_device.h>
#include <linux/mfd/arizona/core.h>
......@@ -236,22 +237,39 @@ static irqreturn_t arizona_overclocked(int irq, void *data)
#define ARIZONA_REG_POLL_DELAY_US 7500
static inline bool arizona_poll_reg_delay(ktime_t timeout)
{
if (ktime_compare(ktime_get(), timeout) > 0)
return false;
usleep_range(ARIZONA_REG_POLL_DELAY_US / 2, ARIZONA_REG_POLL_DELAY_US);
return true;
}
static int arizona_poll_reg(struct arizona *arizona,
int timeout_ms, unsigned int reg,
unsigned int mask, unsigned int target)
{
ktime_t timeout = ktime_add_us(ktime_get(), timeout_ms * USEC_PER_MSEC);
unsigned int val = 0;
int ret;
ret = regmap_read_poll_timeout(arizona->regmap,
reg, val, ((val & mask) == target),
ARIZONA_REG_POLL_DELAY_US,
timeout_ms * 1000);
if (ret)
dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n",
reg, val);
do {
ret = regmap_read(arizona->regmap, reg, &val);
return ret;
if ((val & mask) == target)
return 0;
} while (arizona_poll_reg_delay(timeout));
if (ret) {
dev_err(arizona->dev, "Failed polling reg 0x%x: %d\n",
reg, ret);
return ret;
}
dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n", reg, val);
return -ETIMEDOUT;
}
static int arizona_wait_for_boot(struct arizona *arizona)
......
......@@ -349,6 +349,8 @@ static int as3722_i2c_of_probe(struct i2c_client *i2c,
"ams,enable-internal-int-pullup");
as3722->en_intern_i2c_pullup = of_property_read_bool(np,
"ams,enable-internal-i2c-pullup");
as3722->en_ac_ok_pwr_on = of_property_read_bool(np,
"ams,enable-ac-ok-power-on");
as3722->irq_flags = irqd_get_trigger_type(irq_data);
dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags);
return 0;
......@@ -360,6 +362,7 @@ static int as3722_i2c_probe(struct i2c_client *i2c,
struct as3722 *as3722;
unsigned long irq_flags;
int ret;
u8 val = 0;
as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL);
if (!as3722)
......@@ -398,6 +401,15 @@ static int as3722_i2c_probe(struct i2c_client *i2c,
if (ret < 0)
return ret;
if (as3722->en_ac_ok_pwr_on)
val = AS3722_CTRL_SEQU1_AC_OK_PWR_ON;
ret = as3722_update_bits(as3722, AS3722_CTRL_SEQU1_REG,
AS3722_CTRL_SEQU1_AC_OK_PWR_ON, val);
if (ret < 0) {
dev_err(as3722->dev, "CTRLsequ1 update failed: %d\n", ret);
return ret;
}
ret = devm_mfd_add_devices(&i2c->dev, -1, as3722_devs,
ARRAY_SIZE(as3722_devs), NULL, 0,
regmap_irq_get_domain(as3722->irq_data));
......
......@@ -65,6 +65,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
{ .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
{ },
};
MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
......@@ -74,6 +75,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
{ "axp202", 0 },
{ "axp209", 0 },
{ "axp221", 0 },
{ "axp806", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
......
......@@ -221,6 +221,11 @@ static const struct resource axp803_pek_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
};
static const struct resource axp806_pek_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_RISE, "PEK_DBR"),
DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_FALL, "PEK_DBF"),
};
static const struct resource axp809_pek_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
......@@ -730,6 +735,15 @@ static const struct mfd_cell axp803_cells[] = {
{ .name = "axp20x-regulator" },
};
static const struct mfd_cell axp806_self_working_cells[] = {
{
.name = "axp221-pek",
.num_resources = ARRAY_SIZE(axp806_pek_resources),
.resources = axp806_pek_resources,
},
{ .name = "axp20x-regulator" },
};
static const struct mfd_cell axp806_cells[] = {
{
.id = 2,
......@@ -842,8 +856,14 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
break;
case AXP806_ID:
axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
axp20x->cells = axp806_cells;
if (of_property_read_bool(axp20x->dev->of_node,
"x-powers,self-working-mode")) {
axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
axp20x->cells = axp806_self_working_cells;
} else {
axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
axp20x->cells = axp806_cells;
}
axp20x->regmap_cfg = &axp806_regmap_config;
axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
break;
......@@ -901,7 +921,9 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
*/
if (axp20x->variant == AXP806_ID) {
if (of_property_read_bool(axp20x->dev->of_node,
"x-powers,master-mode"))
"x-powers,master-mode") ||
of_property_read_bool(axp20x->dev->of_node,
"x-powers,self-working-mode"))
regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
else
......
......@@ -378,10 +378,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
kfree(msg);
}
static const struct mfd_cell cros_ec_cec_cells[] = {
{ .name = "cros-ec-cec" }
};
static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc" }
};
static const struct mfd_cell cros_usbpd_charger_cells[] = {
{ .name = "cros-usbpd-charger" }
};
static int ec_device_probe(struct platform_device *pdev)
{
int retval = -ENOMEM;
......@@ -420,6 +428,18 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
/* Check whether this EC instance has CEC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
cros_ec_cec_cells,
ARRAY_SIZE(cros_ec_cec_cells),
NULL, 0, NULL);
if (retval)
dev_err(ec->dev,
"failed to add cros-ec-cec device: %d\n",
retval);
}
/* Check whether this EC instance has RTC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
......@@ -432,6 +452,18 @@ static int ec_device_probe(struct platform_device *pdev)
retval);
}
/* Check whether this EC instance has the PD charge manager */
if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
cros_usbpd_charger_cells,
ARRAY_SIZE(cros_usbpd_charger_cells),
NULL, 0, NULL);
if (retval)
dev_err(ec->dev,
"failed to add cros-usbpd-charger device: %d\n",
retval);
}
/* Take control of the lightbar from the EC. */
lb_manual_suspend_ctrl(ec, 1);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Regmap tables for CS47L35 codec
*
* Copyright (C) 2015-2017 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/mfd/madera/core.h>
#include <linux/mfd/madera/registers.h>
#include "madera.h"
static const struct reg_sequence cs47l35_reva_16_patch[] = {
{ 0x460, 0x0c40 },
{ 0x461, 0xcd1a },
{ 0x462, 0x0c40 },
{ 0x463, 0xb53b },
{ 0x464, 0x0c40 },
{ 0x465, 0x7503 },
{ 0x466, 0x0c40 },
{ 0x467, 0x4a41 },
{ 0x468, 0x0041 },
{ 0x469, 0x3491 },
{ 0x46a, 0x0841 },
{ 0x46b, 0x1f50 },
{ 0x46c, 0x0446 },
{ 0x46d, 0x14ed },
{ 0x46e, 0x0446 },
{ 0x46f, 0x1455 },
{ 0x470, 0x04c6 },
{ 0x471, 0x1220 },
{ 0x472, 0x04c6 },
{ 0x473, 0x040f },
{ 0x474, 0x04ce },
{ 0x475, 0x0339 },
{ 0x476, 0x05df },
{ 0x477, 0x028f },
{ 0x478, 0x05df },
{ 0x479, 0x0209 },
{ 0x47a, 0x05df },
{ 0x47b, 0x00cf },
{ 0x47c, 0x05df },
{ 0x47d, 0x0001 },
{ 0x47e, 0x07ff },
};
int cs47l35_patch(struct madera *madera)
{
int ret;
ret = regmap_register_patch(madera->regmap, cs47l35_reva_16_patch,
ARRAY_SIZE(cs47l35_reva_16_patch));
if (ret < 0)
dev_err(madera->dev, "Error applying patch: %d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(cs47l35_patch);
static const struct reg_default cs47l35_reg_default[] = {
{ 0x00000020, 0x0000 }, /* R32 (0x20) - Tone Generator 1 */
{ 0x00000021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
{ 0x00000022, 0x0000 }, /* R34 (0x22) - Tone Generator 3 */
{ 0x00000023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
{ 0x00000024, 0x0000 }, /* R36 (0x24) - Tone Generator 5 */
{ 0x00000030, 0x0000 }, /* R48 (0x30) - PWM Drive 1 */
{ 0x00000031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
{ 0x00000032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
{ 0x00000061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
{ 0x00000062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
{ 0x00000063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
{ 0x00000064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4*/
{ 0x00000066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence Select 1*/
{ 0x00000067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence Select 2*/
{ 0x00000090, 0x0000 }, /* R144 (0x90) - Haptics Control 1 */
{ 0x00000091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
{ 0x00000092, 0x0000 }, /* R146 (0x92) - Haptics phase 1 intensity */
{ 0x00000093, 0x0000 }, /* R147 (0x93) - Haptics phase 1 duration */
{ 0x00000094, 0x0000 }, /* R148 (0x94) - Haptics phase 2 intensity */
{ 0x00000095, 0x0000 }, /* R149 (0x95) - Haptics phase 2 duration */
{ 0x00000096, 0x0000 }, /* R150 (0x96) - Haptics phase 3 intensity */
{ 0x00000097, 0x0000 }, /* R151 (0x97) - Haptics phase 3 duration */
{ 0x000000A0, 0x0000 }, /* R160 (0xa0) - Comfort Noise Generator */
{ 0x00000100, 0x0002 }, /* R256 (0x100) - Clock 32k 1 */
{ 0x00000101, 0x0404 }, /* R257 (0x101) - System Clock 1 */
{ 0x00000102, 0x0011 }, /* R258 (0x102) - Sample rate 1 */
{ 0x00000103, 0x0011 }, /* R259 (0x103) - Sample rate 2 */
{ 0x00000104, 0x0011 }, /* R260 (0x104) - Sample rate 3 */
{ 0x00000120, 0x0305 }, /* R288 (0x120) - DSP Clock 1 */
{ 0x00000122, 0x0000 }, /* R290 (0x122) - DSP Clock 2 */
{ 0x00000149, 0x0000 }, /* R329 (0x149) - Output system clock */
{ 0x0000014a, 0x0000 }, /* R330 (0x14a) - Output async clock */
{ 0x00000152, 0x0000 }, /* R338 (0x152) - Rate Estimator 1 */
{ 0x00000153, 0x0000 }, /* R339 (0x153) - Rate Estimator 2 */
{ 0x00000154, 0x0000 }, /* R340 (0x154) - Rate Estimator 3 */
{ 0x00000155, 0x0000 }, /* R341 (0x155) - Rate Estimator 4 */
{ 0x00000156, 0x0000 }, /* R342 (0x156) - Rate Estimator 5 */
{ 0x00000171, 0x0002 }, /* R369 (0x171) - FLL1 Control 1 */
{ 0x00000172, 0x0008 }, /* R370 (0x172) - FLL1 Control 2 */
{ 0x00000173, 0x0018 }, /* R371 (0x173) - FLL1 Control 3 */
{ 0x00000174, 0x007d }, /* R372 (0x174) - FLL1 Control 4 */
{ 0x00000175, 0x0000 }, /* R373 (0x175) - FLL1 Control 5 */
{ 0x00000176, 0x0000 }, /* R374 (0x176) - FLL1 Control 6 */
{ 0x00000177, 0x0281 }, /* R375 (0x177) - FLL1 Loop Filter Test 1 */
{ 0x00000179, 0x0000 }, /* R377 (0x179) - FLL1 Control 7 */
{ 0x0000017a, 0x0b06 }, /* R378 (0x17a) - FLL1 EFS2 */
{ 0x0000017f, 0x0000 }, /* R383 (0x17f) - FLL1 Synchroniser 1 */
{ 0x00000180, 0x0000 }, /* R384 (0x180) - FLL1 Synchroniser 2 */
{ 0x00000181, 0x0000 }, /* R385 (0x181) - FLL1 Synchroniser 3 */
{ 0x00000182, 0x0000 }, /* R386 (0x182) - FLL1 Synchroniser 4 */
{ 0x00000183, 0x0000 }, /* R387 (0x183) - FLL1 Synchroniser 5 */
{ 0x00000184, 0x0000 }, /* R388 (0x184) - FLL1 Synchroniser 6 */
{ 0x00000185, 0x0001 }, /* R389 (0x185) - FLL1 Synchroniser 7 */
{ 0x00000187, 0x0000 }, /* R391 (0x187) - FLL1 Spread Spectrum */
{ 0x00000188, 0x000c }, /* R392 (0x188) - FLL1 GPIO Clock */
{ 0x00000200, 0x0006 }, /* R512 (0x200) - Mic Charge Pump 1 */
{ 0x0000020b, 0x0400 }, /* R523 (0x20b) - HP Charge Pump 8 */
{ 0x00000213, 0x03e4 }, /* R531 (0x213) - LDO2 Control 1 */
{ 0x00000218, 0x00e6 }, /* R536 (0x218) - Mic Bias Ctrl 1 */
{ 0x00000219, 0x00e6 }, /* R537 (0x219) - Mic Bias Ctrl 2 */
{ 0x0000021c, 0x0022 }, /* R540 (0x21c) - Mic Bias Ctrl 5 */
{ 0x0000021e, 0x0022 }, /* R542 (0x21e) - Mic Bias Ctrl 6 */
{ 0x0000027e, 0x0000 }, /* R638 (0x27e) - EDRE HP stereo control */
{ 0x00000293, 0x0080 }, /* R659 (0x293) - Accessory Detect Mode 1 */
{ 0x0000029b, 0x0000 }, /* R667 (0x29b) - Headphone Detect 1 */
{ 0x000002a3, 0x1102 }, /* R675 (0x2a3) - Mic Detect Control 1 */
{ 0x000002a4, 0x009f }, /* R676 (0x2a4) - Mic Detect Control 2 */
{ 0x000002a6, 0x3d3d }, /* R678 (0x2a6) - Mic Detect Level 1 */
{ 0x000002a7, 0x3d3d }, /* R679 (0x2a7) - Mic Detect Level 2 */
{ 0x000002a8, 0x333d }, /* R680 (0x2a8) - Mic Detect Level 3 */
{ 0x000002a9, 0x202d }, /* R681 (0x2a9) - Mic Detect Level 4 */
{ 0x000002c6, 0x0010 }, /* R710 (0x2c5) - Mic Clamp control */
{ 0x000002c8, 0x0000 }, /* R712 (0x2c8) - GP switch 1 */
{ 0x000002d3, 0x0000 }, /* R723 (0x2d3) - Jack detect analogue */
{ 0x00000300, 0x0000 }, /* R768 (0x300) - Input Enables */
{ 0x00000308, 0x0000 }, /* R776 (0x308) - Input Rate */
{ 0x00000309, 0x0022 }, /* R777 (0x309) - Input Volume Ramp */
{ 0x0000030c, 0x0002 }, /* R780 (0x30c) - HPF Control */
{ 0x00000310, 0x0080 }, /* R784 (0x310) - IN1L Control */
{ 0x00000311, 0x0180 }, /* R785 (0x311) - ADC Digital Volume 1L */
{ 0x00000312, 0x0500 }, /* R786 (0x312) - DMIC1L Control */
{ 0x00000314, 0x0080 }, /* R788 (0x314) - IN1R Control */
{ 0x00000315, 0x0180 }, /* R789 (0x315) - ADC Digital Volume 1R */
{ 0x00000316, 0x0000 }, /* R790 (0x316) - DMIC1R Control */
{ 0x00000318, 0x0080 }, /* R792 (0x318) - IN2L Control */
{ 0x00000319, 0x0180 }, /* R793 (0x319) - ADC Digital Volume 2L */
{ 0x0000031a, 0x0500 }, /* R794 (0x31a) - DMIC2L Control */
{ 0x0000031c, 0x0080 }, /* R796 (0x31c) - IN2R Control */
{ 0x0000031d, 0x0180 }, /* R797 (0x31d) - ADC Digital Volume 2R */
{ 0x0000031e, 0x0000 }, /* R798 (0x31e) - DMIC2R Control */
{ 0x00000400, 0x0000 }, /* R1024 (0x400) - Output Enables 1 */
{ 0x00000408, 0x0000 }, /* R1032 (0x408) - Output Rate 1 */
{ 0x00000409, 0x0022 }, /* R1033 (0x409) - Output Volume Ramp */
{ 0x00000410, 0x0080 }, /* R1040 (0x410) - Output Path Config 1L */
{ 0x00000411, 0x0180 }, /* R1041 (0x411) - DAC Digital Volume 1L */
{ 0x00000413, 0x0001 }, /* R1043 (0x413) - Noise Gate Select 1L */
{ 0x00000414, 0x0080 }, /* R1044 (0x414) - Output Path Config 1R */
{ 0x00000415, 0x0180 }, /* R1045 (0x415) - DAC Digital Volume 1R */
{ 0x00000417, 0x0002 }, /* R1047 (0x417) - Noise Gate Select 1R */
{ 0x00000428, 0x0000 }, /* R1064 (0x428) - Output Path Config 4L */
{ 0x00000429, 0x0180 }, /* R1065 (0x429) - DAC Digital Volume 4L */
{ 0x0000042b, 0x0040 }, /* R1067 (0x42b) - Noise Gate Select 4L */
{ 0x00000430, 0x0000 }, /* R1072 (0x430) - Output Path Config 5L */
{ 0x00000431, 0x0180 }, /* R1073 (0x431) - DAC Digital Volume 5L */
{ 0x00000433, 0x0100 }, /* R1075 (0x433) - Noise Gate Select 5L */
{ 0x00000434, 0x0000 }, /* R1076 (0x434) - Output Path Config 5R */
{ 0x00000435, 0x0180 }, /* R1077 (0x435) - DAC Digital Volume 5R */
{ 0x00000437, 0x0200 }, /* R1079 (0x437) - Noise Gate Select 5R */
{ 0x00000440, 0x0003 }, /* R1088 (0x440) - DRE Enable */
{ 0x00000448, 0x0a83 }, /* R1096 (0x448) - eDRE Enable */
{ 0x0000044a, 0x0000 }, /* R1098 (0x44a) - eDRE Manual */
{ 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
{ 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
{ 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
{ 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
{ 0x000004a0, 0x3080 }, /* R1184 (0x4a0) - HP1 Short Circuit Ctrl */
{ 0x000004a8, 0x7120 }, /* R1192 (0x4a8) - HP Test Ctrl 5 */
{ 0x000004a9, 0x7120 }, /* R1193 (0x4a9) - HP Test Ctrl 6 */
{ 0x00000500, 0x000c }, /* R1280 (0x500) - AIF1 BCLK Ctrl */
{ 0x00000501, 0x0000 }, /* R1281 (0x501) - AIF1 Tx Pin Ctrl */
{ 0x00000502, 0x0000 }, /* R1282 (0x502) - AIF1 Rx Pin Ctrl */
{ 0x00000503, 0x0000 }, /* R1283 (0x503) - AIF1 Rate Ctrl */
{ 0x00000504, 0x0000 }, /* R1284 (0x504) - AIF1 Format */
{ 0x00000506, 0x0040 }, /* R1286 (0x506) - AIF1 Rx BCLK Rate */
{ 0x00000507, 0x1818 }, /* R1287 (0x507) - AIF1 Frame Ctrl 1 */
{ 0x00000508, 0x1818 }, /* R1288 (0x508) - AIF1 Frame Ctrl 2 */
{ 0x00000509, 0x0000 }, /* R1289 (0x509) - AIF1 Frame Ctrl 3 */
{ 0x0000050a, 0x0001 }, /* R1290 (0x50a) - AIF1 Frame Ctrl 4 */
{ 0x0000050b, 0x0002 }, /* R1291 (0x50b) - AIF1 Frame Ctrl 5 */
{ 0x0000050c, 0x0003 }, /* R1292 (0x50c) - AIF1 Frame Ctrl 6 */
{ 0x0000050d, 0x0004 }, /* R1293 (0x50d) - AIF1 Frame Ctrl 7 */
{ 0x0000050e, 0x0005 }, /* R1294 (0x50e) - AIF1 Frame Ctrl 8 */
{ 0x00000511, 0x0000 }, /* R1297 (0x511) - AIF1 Frame Ctrl 11 */
{ 0x00000512, 0x0001 }, /* R1298 (0x512) - AIF1 Frame Ctrl 12 */
{ 0x00000513, 0x0002 }, /* R1299 (0x513) - AIF1 Frame Ctrl 13 */
{ 0x00000514, 0x0003 }, /* R1300 (0x514) - AIF1 Frame Ctrl 14 */
{ 0x00000515, 0x0004 }, /* R1301 (0x515) - AIF1 Frame Ctrl 15 */
{ 0x00000516, 0x0005 }, /* R1302 (0x516) - AIF1 Frame Ctrl 16 */
{ 0x00000519, 0x0000 }, /* R1305 (0x519) - AIF1 Tx Enables */
{ 0x0000051a, 0x0000 }, /* R1306 (0x51a) - AIF1 Rx Enables */
{ 0x00000540, 0x000c }, /* R1344 (0x540) - AIF2 BCLK Ctrl */
{ 0x00000541, 0x0000 }, /* R1345 (0x541) - AIF2 Tx Pin Ctrl */
{ 0x00000542, 0x0000 }, /* R1346 (0x542) - AIF2 Rx Pin Ctrl */
{ 0x00000543, 0x0000 }, /* R1347 (0x543) - AIF2 Rate Ctrl */
{ 0x00000544, 0x0000 }, /* R1348 (0x544) - AIF2 Format */
{ 0x00000546, 0x0040 }, /* R1350 (0x546) - AIF2 Rx BCLK Rate */
{ 0x00000547, 0x1818 }, /* R1351 (0x547) - AIF2 Frame Ctrl 1 */
{ 0x00000548, 0x1818 }, /* R1352 (0x548) - AIF2 Frame Ctrl 2 */
{ 0x00000549, 0x0000 }, /* R1353 (0x549) - AIF2 Frame Ctrl 3 */
{ 0x0000054a, 0x0001 }, /* R1354 (0x54a) - AIF2 Frame Ctrl 4 */
{ 0x00000551, 0x0000 }, /* R1361 (0x551) - AIF2 Frame Ctrl 11 */
{ 0x00000552, 0x0001 }, /* R1362 (0x552) - AIF2 Frame Ctrl 12 */
{ 0x00000559, 0x0000 }, /* R1369 (0x559) - AIF2 Tx Enables */
{ 0x0000055a, 0x0000 }, /* R1370 (0x55a) - AIF2 Rx Enables */
{ 0x00000580, 0x000c }, /* R1408 (0x580) - AIF3 BCLK Ctrl */
{ 0x00000581, 0x0000 }, /* R1409 (0x581) - AIF3 Tx Pin Ctrl */
{ 0x00000582, 0x0000 }, /* R1410 (0x582) - AIF3 Rx Pin Ctrl */
{ 0x00000583, 0x0000 }, /* R1411 (0x583) - AIF3 Rate Ctrl */
{ 0x00000584, 0x0000 }, /* R1412 (0x584) - AIF3 Format */
{ 0x00000586, 0x0040 }, /* R1414 (0x586) - AIF3 Rx BCLK Rate */
{ 0x00000587, 0x1818 }, /* R1415 (0x587) - AIF3 Frame Ctrl 1 */
{ 0x00000588, 0x1818 }, /* R1416 (0x588) - AIF3 Frame Ctrl 2 */
{ 0x00000589, 0x0000 }, /* R1417 (0x589) - AIF3 Frame Ctrl 3 */
{ 0x0000058a, 0x0001 }, /* R1418 (0x58a) - AIF3 Frame Ctrl 4 */
{ 0x00000591, 0x0000 }, /* R1425 (0x591) - AIF3 Frame Ctrl 11 */
{ 0x00000592, 0x0001 }, /* R1426 (0x592) - AIF3 Frame Ctrl 12 */
{ 0x00000599, 0x0000 }, /* R1433 (0x599) - AIF3 Tx Enables */
{ 0x0000059a, 0x0000 }, /* R1434 (0x59a) - AIF3 Rx Enables */
{ 0x000005c2, 0x0000 }, /* R1474 (0x5c2) - SPD1 TX Control */
{ 0x000005e3, 0x0000 }, /* R1507 (0x5e3) - SLIMbus Framer Ref Gear */
{ 0x000005e5, 0x0000 }, /* R1509 (0x5e5) - SLIMbus Rates 1 */
{ 0x000005e6, 0x0000 }, /* R1510 (0x5e6) - SLIMbus Rates 2 */
{ 0x000005e7, 0x0000 }, /* R1511 (0x5e7) - SLIMbus Rates 3 */
{ 0x000005e9, 0x0000 }, /* R1513 (0x5e9) - SLIMbus Rates 5 */
{ 0x000005ea, 0x0000 }, /* R1514 (0x5ea) - SLIMbus Rates 6 */
{ 0x000005eb, 0x0000 }, /* R1515 (0x5eb) - SLIMbus Rates 7 */
{ 0x000005f5, 0x0000 }, /* R1525 (0x5f5) - SLIMbus RX Channel Enable */
{ 0x000005f6, 0x0000 }, /* R1526 (0x5f6) - SLIMbus TX Channel Enable */
{ 0x00000640, 0x0000 }, /* R1600 (0x640) - PWM1MIX Input 1 Source */
{ 0x00000641, 0x0080 }, /* R1601 (0x641) - PWM1MIX Input 1 Volume */
{ 0x00000642, 0x0000 }, /* R1602 (0x642) - PWM1MIX Input 2 Source */
{ 0x00000643, 0x0080 }, /* R1603 (0x643) - PWM1MIX Input 2 Volume */
{ 0x00000644, 0x0000 }, /* R1604 (0x644) - PWM1MIX Input 3 Source */
{ 0x00000645, 0x0080 }, /* R1605 (0x645) - PWM1MIX Input 3 Volume */
{ 0x00000646, 0x0000 }, /* R1606 (0x646) - PWM1MIX Input 4 Source */
{ 0x00000647, 0x0080 }, /* R1607 (0x647) - PWM1MIX Input 4 Volume */
{ 0x00000648, 0x0000 }, /* R1608 (0x648) - PWM2MIX Input 1 Source */
{ 0x00000649, 0x0080 }, /* R1609 (0x649) - PWM2MIX Input 1 Volume */
{ 0x0000064a, 0x0000 }, /* R1610 (0x64a) - PWM2MIX Input 2 Source */
{ 0x0000064b, 0x0080 }, /* R1611 (0x64b) - PWM2MIX Input 2 Volume */
{ 0x0000064c, 0x0000 }, /* R1612 (0x64c) - PWM2MIX Input 3 Source */
{ 0x0000064d, 0x0080 }, /* R1613 (0x64d) - PWM2MIX Input 3 Volume */
{ 0x0000064e, 0x0000 }, /* R1614 (0x64e) - PWM2MIX Input 4 Source */
{ 0x0000064f, 0x0080 }, /* R1615 (0x64f) - PWM2MIX Input 4 Volume */
{ 0x00000680, 0x0000 }, /* R1664 (0x680) - OUT1LMIX Input 1 Source */
{ 0x00000681, 0x0080 }, /* R1665 (0x681) - OUT1LMIX Input 1 Volume */
{ 0x00000682, 0x0000 }, /* R1666 (0x682) - OUT1LMIX Input 2 Source */
{ 0x00000683, 0x0080 }, /* R1667 (0x683) - OUT1LMIX Input 2 Volume */
{ 0x00000684, 0x0000 }, /* R1668 (0x684) - OUT1LMIX Input 3 Source */
{ 0x00000685, 0x0080 }, /* R1669 (0x685) - OUT1LMIX Input 3 Volume */
{ 0x00000686, 0x0000 }, /* R1670 (0x686) - OUT1LMIX Input 4 Source */
{ 0x00000687, 0x0080 }, /* R1671 (0x687) - OUT1LMIX Input 4 Volume */
{ 0x00000688, 0x0000 }, /* R1672 (0x688) - OUT1RMIX Input 1 Source */
{ 0x00000689, 0x0080 }, /* R1673 (0x689) - OUT1RMIX Input 1 Volume */
{ 0x0000068a, 0x0000 }, /* R1674 (0x68a) - OUT1RMIX Input 2 Source */
{ 0x0000068b, 0x0080 }, /* R1675 (0x68b) - OUT1RMIX Input 2 Volume */
{ 0x0000068c, 0x0000 }, /* R1672 (0x68c) - OUT1RMIX Input 3 Source */
{ 0x0000068d, 0x0080 }, /* R1673 (0x68d) - OUT1RMIX Input 3 Volume */
{ 0x0000068e, 0x0000 }, /* R1674 (0x68e) - OUT1RMIX Input 4 Source */
{ 0x0000068f, 0x0080 }, /* R1675 (0x68f) - OUT1RMIX Input 4 Volume */
{ 0x000006b0, 0x0000 }, /* R1712 (0x6b0) - OUT4LMIX Input 1 Source */
{ 0x000006b1, 0x0080 }, /* R1713 (0x6b1) - OUT4LMIX Input 1 Volume */
{ 0x000006b2, 0x0000 }, /* R1714 (0x6b2) - OUT4LMIX Input 2 Source */
{ 0x000006b3, 0x0080 }, /* R1715 (0x6b3) - OUT4LMIX Input 2 Volume */
{ 0x000006b4, 0x0000 }, /* R1716 (0x6b4) - OUT4LMIX Input 3 Source */
{ 0x000006b5, 0x0080 }, /* R1717 (0x6b5) - OUT4LMIX Input 3 Volume */
{ 0x000006b6, 0x0000 }, /* R1718 (0x6b6) - OUT4LMIX Input 4 Source */
{ 0x000006b7, 0x0080 }, /* R1719 (0x6b7) - OUT4LMIX Input 4 Volume */
{ 0x000006c0, 0x0000 }, /* R1728 (0x6c0) - OUT5LMIX Input 1 Source */
{ 0x000006c1, 0x0080 }, /* R1729 (0x6c1) - OUT5LMIX Input 1 Volume */
{ 0x000006c2, 0x0000 }, /* R1730 (0x6c2) - OUT5LMIX Input 2 Source */
{ 0x000006c3, 0x0080 }, /* R1731 (0x6c3) - OUT5LMIX Input 2 Volume */
{ 0x000006c4, 0x0000 }, /* R1732 (0x6c4) - OUT5LMIX Input 3 Source */
{ 0x000006c5, 0x0080 }, /* R1733 (0x6c5) - OUT5LMIX Input 3 Volume */
{ 0x000006c6, 0x0000 }, /* R1734 (0x6c6) - OUT5LMIX Input 4 Source */
{ 0x000006c7, 0x0080 }, /* R1735 (0x6c7) - OUT5LMIX Input 4 Volume */
{ 0x000006c8, 0x0000 }, /* R1736 (0x6c8) - OUT5RMIX Input 1 Source */
{ 0x000006c9, 0x0080 }, /* R1737 (0x6c9) - OUT5RMIX Input 1 Volume */
{ 0x000006ca, 0x0000 }, /* R1738 (0x6ca) - OUT5RMIX Input 2 Source */
{ 0x000006cb, 0x0080 }, /* R1739 (0x6cb) - OUT5RMIX Input 2 Volume */
{ 0x000006cc, 0x0000 }, /* R1740 (0x6cc) - OUT5RMIX Input 3 Source */
{ 0x000006cd, 0x0080 }, /* R1741 (0x6cd) - OUT5RMIX Input 3 Volume */
{ 0x000006ce, 0x0000 }, /* R1742 (0x6ce) - OUT5RMIX Input 4 Source */
{ 0x000006cf, 0x0080 }, /* R1743 (0x6cf) - OUT5RMIX Input 4 Volume */
{ 0x00000700, 0x0000 }, /* R1792 (0x700) - AIF1TX1MIX Input 1 Source */
{ 0x00000701, 0x0080 }, /* R1793 (0x701) - AIF1TX1MIX Input 1 Volume */
{ 0x00000702, 0x0000 }, /* R1794 (0x702) - AIF1TX1MIX Input 2 Source */
{ 0x00000703, 0x0080 }, /* R1795 (0x703) - AIF1TX1MIX Input 2 Volume */
{ 0x00000704, 0x0000 }, /* R1796 (0x704) - AIF1TX1MIX Input 3 Source */
{ 0x00000705, 0x0080 }, /* R1797 (0x705) - AIF1TX1MIX Input 3 Volume */
{ 0x00000706, 0x0000 }, /* R1798 (0x706) - AIF1TX1MIX Input 4 Source */
{ 0x00000707, 0x0080 }, /* R1799 (0x707) - AIF1TX1MIX Input 4 Volume */
{ 0x00000708, 0x0000 }, /* R1800 (0x708) - AIF1TX2MIX Input 1 Source */
{ 0x00000709, 0x0080 }, /* R1801 (0x709) - AIF1TX2MIX Input 1 Volume */
{ 0x0000070a, 0x0000 }, /* R1802 (0x70a) - AIF1TX2MIX Input 2 Source */
{ 0x0000070b, 0x0080 }, /* R1803 (0x70b) - AIF1TX2MIX Input 2 Volume */
{ 0x0000070c, 0x0000 }, /* R1804 (0x70c) - AIF1TX2MIX Input 3 Source */
{ 0x0000070d, 0x0080 }, /* R1805 (0x70d) - AIF1TX2MIX Input 3 Volume */
{ 0x0000070e, 0x0000 }, /* R1806 (0x70e) - AIF1TX2MIX Input 4 Source */
{ 0x0000070f, 0x0080 }, /* R1807 (0x70f) - AIF1TX2MIX Input 4 Volume */
{ 0x00000710, 0x0000 }, /* R1808 (0x710) - AIF1TX3MIX Input 1 Source */
{ 0x00000711, 0x0080 }, /* R1809 (0x711) - AIF1TX3MIX Input 1 Volume */
{ 0x00000712, 0x0000 }, /* R1810 (0x712) - AIF1TX3MIX Input 2 Source */
{ 0x00000713, 0x0080 }, /* R1811 (0x713) - AIF1TX3MIX Input 2 Volume */
{ 0x00000714, 0x0000 }, /* R1812 (0x714) - AIF1TX3MIX Input 3 Source */
{ 0x00000715, 0x0080 }, /* R1813 (0x715) - AIF1TX3MIX Input 3 Volume */
{ 0x00000716, 0x0000 }, /* R1814 (0x716) - AIF1TX3MIX Input 4 Source */
{ 0x00000717, 0x0080 }, /* R1815 (0x717) - AIF1TX3MIX Input 4 Volume */
{ 0x00000718, 0x0000 }, /* R1816 (0x718) - AIF1TX4MIX Input 1 Source */
{ 0x00000719, 0x0080 }, /* R1817 (0x719) - AIF1TX4MIX Input 1 Volume */
{ 0x0000071a, 0x0000 }, /* R1818 (0x71a) - AIF1TX4MIX Input 2 Source */
{ 0x0000071b, 0x0080 }, /* R1819 (0x71b) - AIF1TX4MIX Input 2 Volume */
{ 0x0000071c, 0x0000 }, /* R1820 (0x71c) - AIF1TX4MIX Input 3 Source */
{ 0x0000071d, 0x0080 }, /* R1821 (0x71d) - AIF1TX4MIX Input 3 Volume */
{ 0x0000071e, 0x0000 }, /* R1822 (0x71e) - AIF1TX4MIX Input 4 Source */
{ 0x0000071f, 0x0080 }, /* R1823 (0x71f) - AIF1TX4MIX Input 4 Volume */
{ 0x00000720, 0x0000 }, /* R1824 (0x720) - AIF1TX5MIX Input 1 Source */
{ 0x00000721, 0x0080 }, /* R1825 (0x721) - AIF1TX5MIX Input 1 Volume */
{ 0x00000722, 0x0000 }, /* R1826 (0x722) - AIF1TX5MIX Input 2 Source */
{ 0x00000723, 0x0080 }, /* R1827 (0x723) - AIF1TX5MIX Input 2 Volume */
{ 0x00000724, 0x0000 }, /* R1828 (0x724) - AIF1TX5MIX Input 3 Source */
{ 0x00000725, 0x0080 }, /* R1829 (0x725) - AIF1TX5MIX Input 3 Volume */
{ 0x00000726, 0x0000 }, /* R1830 (0x726) - AIF1TX5MIX Input 4 Source */
{ 0x00000727, 0x0080 }, /* R1831 (0x727) - AIF1TX5MIX Input 4 Volume */
{ 0x00000728, 0x0000 }, /* R1832 (0x728) - AIF1TX6MIX Input 1 Source */
{ 0x00000729, 0x0080 }, /* R1833 (0x729) - AIF1TX6MIX Input 1 Volume */
{ 0x0000072a, 0x0000 }, /* R1834 (0x72a) - AIF1TX6MIX Input 2 Source */
{ 0x0000072b, 0x0080 }, /* R1835 (0x72b) - AIF1TX6MIX Input 2 Volume */
{ 0x0000072c, 0x0000 }, /* R1836 (0x72c) - AIF1TX6MIX Input 3 Source */
{ 0x0000072d, 0x0080 }, /* R1837 (0x72d) - AIF1TX6MIX Input 3 Volume */
{ 0x0000072e, 0x0000 }, /* R1838 (0x72e) - AIF1TX6MIX Input 4 Source */
{ 0x0000072f, 0x0080 }, /* R1839 (0x72f) - AIF1TX6MIX Input 4 Volume */
{ 0x00000740, 0x0000 }, /* R1856 (0x740) - AIF2TX1MIX Input 1 Source */
{ 0x00000741, 0x0080 }, /* R1857 (0x741) - AIF2TX1MIX Input 1 Volume */
{ 0x00000742, 0x0000 }, /* R1858 (0x742) - AIF2TX1MIX Input 2 Source */
{ 0x00000743, 0x0080 }, /* R1859 (0x743) - AIF2TX1MIX Input 2 Volume */
{ 0x00000744, 0x0000 }, /* R1860 (0x744) - AIF2TX1MIX Input 3 Source */
{ 0x00000745, 0x0080 }, /* R1861 (0x745) - AIF2TX1MIX Input 3 Volume */
{ 0x00000746, 0x0000 }, /* R1862 (0x746) - AIF2TX1MIX Input 4 Source */
{ 0x00000747, 0x0080 }, /* R1863 (0x747) - AIF2TX1MIX Input 4 Volume */
{ 0x00000748, 0x0000 }, /* R1864 (0x748) - AIF2TX2MIX Input 1 Source */
{ 0x00000749, 0x0080 }, /* R1865 (0x749) - AIF2TX2MIX Input 1 Volume */
{ 0x0000074a, 0x0000 }, /* R1866 (0x74a) - AIF2TX2MIX Input 2 Source */
{ 0x0000074b, 0x0080 }, /* R1867 (0x74b) - AIF2TX2MIX Input 2 Volume */
{ 0x0000074c, 0x0000 }, /* R1868 (0x74c) - AIF2TX2MIX Input 3 Source */
{ 0x0000074d, 0x0080 }, /* R1869 (0x74d) - AIF2TX2MIX Input 3 Volume */
{ 0x0000074e, 0x0000 }, /* R1870 (0x74e) - AIF2TX2MIX Input 4 Source */
{ 0x0000074f, 0x0080 }, /* R1871 (0x74f) - AIF2TX2MIX Input 4 Volume */
{ 0x00000780, 0x0000 }, /* R1920 (0x780) - AIF3TX1MIX Input 1 Source */
{ 0x00000781, 0x0080 }, /* R1921 (0x781) - AIF3TX1MIX Input 1 Volume */
{ 0x00000782, 0x0000 }, /* R1922 (0x782) - AIF3TX1MIX Input 2 Source */
{ 0x00000783, 0x0080 }, /* R1923 (0x783) - AIF3TX1MIX Input 2 Volume */
{ 0x00000784, 0x0000 }, /* R1924 (0x784) - AIF3TX1MIX Input 3 Source */
{ 0x00000785, 0x0080 }, /* R1925 (0x785) - AIF3TX1MIX Input 3 Volume */
{ 0x00000786, 0x0000 }, /* R1926 (0x786) - AIF3TX1MIX Input 4 Source */
{ 0x00000787, 0x0080 }, /* R1927 (0x787) - AIF3TX1MIX Input 4 Volume */
{ 0x00000788, 0x0000 }, /* R1928 (0x788) - AIF3TX2MIX Input 1 Source */
{ 0x00000789, 0x0080 }, /* R1929 (0x789) - AIF3TX2MIX Input 1 Volume */
{ 0x0000078a, 0x0000 }, /* R1930 (0x78a) - AIF3TX2MIX Input 2 Source */
{ 0x0000078b, 0x0080 }, /* R1931 (0x78b) - AIF3TX2MIX Input 2 Volume */
{ 0x0000078c, 0x0000 }, /* R1932 (0x78c) - AIF3TX2MIX Input 3 Source */
{ 0x0000078d, 0x0080 }, /* R1933 (0x78d) - AIF3TX2MIX Input 3 Volume */
{ 0x0000078e, 0x0000 }, /* R1934 (0x78e) - AIF3TX2MIX Input 4 Source */
{ 0x0000078f, 0x0080 }, /* R1935 (0x78f) - AIF3TX2MIX Input 4 Volume */
{ 0x000007c0, 0x0000 }, /* R1984 (0x7c0) - SLIMTX1MIX Input 1 Source */
{ 0x000007c1, 0x0080 }, /* R1985 (0x7c1) - SLIMTX1MIX Input 1 Volume */
{ 0x000007c2, 0x0000 }, /* R1986 (0x7c2) - SLIMTX1MIX Input 2 Source */
{ 0x000007c3, 0x0080 }, /* R1987 (0x7c3) - SLIMTX1MIX Input 2 Volume */
{ 0x000007c4, 0x0000 }, /* R1988 (0x7c4) - SLIMTX1MIX Input 3 Source */
{ 0x000007c5, 0x0080 }, /* R1989 (0x7c5) - SLIMTX1MIX Input 3 Volume */
{ 0x000007c6, 0x0000 }, /* R1990 (0x7c6) - SLIMTX1MIX Input 4 Source */
{ 0x000007c7, 0x0080 }, /* R1991 (0x7c7) - SLIMTX1MIX Input 4 Volume */
{ 0x000007c8, 0x0000 }, /* R1992 (0x7c8) - SLIMTX2MIX Input 1 Source */
{ 0x000007c9, 0x0080 }, /* R1993 (0x7c9) - SLIMTX2MIX Input 1 Volume */
{ 0x000007ca, 0x0000 }, /* R1994 (0x7ca) - SLIMTX2MIX Input 2 Source */
{ 0x000007cb, 0x0080 }, /* R1995 (0x7cb) - SLIMTX2MIX Input 2 Volume */
{ 0x000007cc, 0x0000 }, /* R1996 (0x7cc) - SLIMTX2MIX Input 3 Source */
{ 0x000007cd, 0x0080 }, /* R1997 (0x7cd) - SLIMTX2MIX Input 3 Volume */
{ 0x000007ce, 0x0000 }, /* R1998 (0x7ce) - SLIMTX2MIX Input 4 Source */
{ 0x000007cf, 0x0080 }, /* R1999 (0x7cf) - SLIMTX2MIX Input 4 Volume */
{ 0x000007d0, 0x0000 }, /* R2000 (0x7d0) - SLIMTX3MIX Input 1 Source */
{ 0x000007d1, 0x0080 }, /* R2001 (0x7d1) - SLIMTX3MIX Input 1 Volume */
{ 0x000007d2, 0x0000 }, /* R2002 (0x7d2) - SLIMTX3MIX Input 2 Source */
{ 0x000007d3, 0x0080 }, /* R2003 (0x7d3) - SLIMTX3MIX Input 2 Volume */
{ 0x000007d4, 0x0000 }, /* R2004 (0x7d4) - SLIMTX3MIX Input 3 Source */
{ 0x000007d5, 0x0080 }, /* R2005 (0x7d5) - SLIMTX3MIX Input 3 Volume */
{ 0x000007d6, 0x0000 }, /* R2006 (0x7d6) - SLIMTX3MIX Input 4 Source */
{ 0x000007d7, 0x0080 }, /* R2007 (0x7d7) - SLIMTX3MIX Input 4 Volume */
{ 0x000007d8, 0x0000 }, /* R2008 (0x7d8) - SLIMTX4MIX Input 1 Source */
{ 0x000007d9, 0x0080 }, /* R2009 (0x7d9) - SLIMTX4MIX Input 1 Volume */
{ 0x000007da, 0x0000 }, /* R2010 (0x7da) - SLIMTX4MIX Input 2 Source */
{ 0x000007db, 0x0080 }, /* R2011 (0x7db) - SLIMTX4MIX Input 2 Volume */
{ 0x000007dc, 0x0000 }, /* R2012 (0x7dc) - SLIMTX4MIX Input 3 Source */
{ 0x000007dd, 0x0080 }, /* R2013 (0x7dd) - SLIMTX4MIX Input 3 Volume */
{ 0x000007de, 0x0000 }, /* R2014 (0x7de) - SLIMTX4MIX Input 4 Source */
{ 0x000007df, 0x0080 }, /* R2015 (0x7df) - SLIMTX4MIX Input 4 Volume */
{ 0x000007e0, 0x0000 }, /* R2016 (0x7e0) - SLIMTX5MIX Input 1 Source */
{ 0x000007e1, 0x0080 }, /* R2017 (0x7e1) - SLIMTX5MIX Input 1 Volume */
{ 0x000007e2, 0x0000 }, /* R2018 (0x7e2) - SLIMTX5MIX Input 2 Source */
{ 0x000007e3, 0x0080 }, /* R2019 (0x7e3) - SLIMTX5MIX Input 2 Volume */
{ 0x000007e4, 0x0000 }, /* R2020 (0x7e4) - SLIMTX5MIX Input 3 Source */
{ 0x000007e5, 0x0080 }, /* R2021 (0x7e5) - SLIMTX5MIX Input 3 Volume */
{ 0x000007e6, 0x0000 }, /* R2022 (0x7e6) - SLIMTX5MIX Input 4 Source */
{ 0x000007e7, 0x0080 }, /* R2023 (0x7e7) - SLIMTX5MIX Input 4 Volume */
{ 0x000007e8, 0x0000 }, /* R2024 (0x7e8) - SLIMTX6MIX Input 1 Source */
{ 0x000007e9, 0x0080 }, /* R2025 (0x7e9) - SLIMTX6MIX Input 1 Volume */
{ 0x000007ea, 0x0000 }, /* R2026 (0x7ea) - SLIMTX6MIX Input 2 Source */
{ 0x000007eb, 0x0080 }, /* R2027 (0x7eb) - SLIMTX6MIX Input 2 Volume */
{ 0x000007ec, 0x0000 }, /* R2028 (0x7ec) - SLIMTX6MIX Input 3 Source */
{ 0x000007ed, 0x0080 }, /* R2029 (0x7ed) - SLIMTX6MIX Input 3 Volume */
{ 0x000007ee, 0x0000 }, /* R2030 (0x7ee) - SLIMTX6MIX Input 4 Source */
{ 0x000007ef, 0x0080 }, /* R2031 (0x7ef) - SLIMTX6MIX Input 4 Volume */
{ 0x00000800, 0x0000 }, /* R2048 (0x800) - SPDIF1TX1MIX Input 1 Source*/
{ 0x00000801, 0x0080 }, /* R2049 (0x801) - SPDIF1TX1MIX Input 1 Volume*/
{ 0x00000808, 0x0000 }, /* R2056 (0x808) - SPDIF1TX2MIX Input 1 Source*/
{ 0x00000809, 0x0080 }, /* R2057 (0x809) - SPDIF1TX2MIX Input 1 Volume*/
{ 0x00000880, 0x0000 }, /* R2176 (0x880) - EQ1MIX Input 1 Source */
{ 0x00000881, 0x0080 }, /* R2177 (0x881) - EQ1MIX Input 1 Volume */
{ 0x00000882, 0x0000 }, /* R2178 (0x882) - EQ1MIX Input 2 Source */
{ 0x00000883, 0x0080 }, /* R2179 (0x883) - EQ1MIX Input 2 Volume */
{ 0x00000884, 0x0000 }, /* R2180 (0x884) - EQ1MIX Input 3 Source */
{ 0x00000885, 0x0080 }, /* R2181 (0x885) - EQ1MIX Input 3 Volume */
{ 0x00000886, 0x0000 }, /* R2182 (0x886) - EQ1MIX Input 4 Source */
{ 0x00000887, 0x0080 }, /* R2183 (0x887) - EQ1MIX Input 4 Volume */
{ 0x00000888, 0x0000 }, /* R2184 (0x888) - EQ2MIX Input 1 Source */
{ 0x00000889, 0x0080 }, /* R2185 (0x889) - EQ2MIX Input 1 Volume */
{ 0x0000088a, 0x0000 }, /* R2186 (0x88a) - EQ2MIX Input 2 Source */
{ 0x0000088b, 0x0080 }, /* R2187 (0x88b) - EQ2MIX Input 2 Volume */
{ 0x0000088c, 0x0000 }, /* R2188 (0x88c) - EQ2MIX Input 3 Source */
{ 0x0000088d, 0x0080 }, /* R2189 (0x88d) - EQ2MIX Input 3 Volume */
{ 0x0000088e, 0x0000 }, /* R2190 (0x88e) - EQ2MIX Input 4 Source */
{ 0x0000088f, 0x0080 }, /* R2191 (0x88f) - EQ2MIX Input 4 Volume */
{ 0x00000890, 0x0000 }, /* R2192 (0x890) - EQ3MIX Input 1 Source */
{ 0x00000891, 0x0080 }, /* R2193 (0x891) - EQ3MIX Input 1 Volume */
{ 0x00000892, 0x0000 }, /* R2194 (0x892) - EQ3MIX Input 2 Source */
{ 0x00000893, 0x0080 }, /* R2195 (0x893) - EQ3MIX Input 2 Volume */
{ 0x00000894, 0x0000 }, /* R2196 (0x894) - EQ3MIX Input 3 Source */
{ 0x00000895, 0x0080 }, /* R2197 (0x895) - EQ3MIX Input 3 Volume */
{ 0x00000896, 0x0000 }, /* R2198 (0x896) - EQ3MIX Input 4 Source */
{ 0x00000897, 0x0080 }, /* R2199 (0x897) - EQ3MIX Input 4 Volume */
{ 0x00000898, 0x0000 }, /* R2200 (0x898) - EQ4MIX Input 1 Source */
{ 0x00000899, 0x0080 }, /* R2201 (0x899) - EQ4MIX Input 1 Volume */
{ 0x0000089a, 0x0000 }, /* R2202 (0x89a) - EQ4MIX Input 2 Source */
{ 0x0000089b, 0x0080 }, /* R2203 (0x89b) - EQ4MIX Input 2 Volume */
{ 0x0000089c, 0x0000 }, /* R2204 (0x89c) - EQ4MIX Input 3 Source */
{ 0x0000089d, 0x0080 }, /* R2205 (0x89d) - EQ4MIX Input 3 Volume */
{ 0x0000089e, 0x0000 }, /* R2206 (0x89e) - EQ4MIX Input 4 Source */
{ 0x0000089f, 0x0080 }, /* R2207 (0x89f) - EQ4MIX Input 4 Volume */
{ 0x000008c0, 0x0000 }, /* R2240 (0x8c0) - DRC1LMIX Input 1 Source */
{ 0x000008c1, 0x0080 }, /* R2241 (0x8c1) - DRC1LMIX Input 1 Volume */
{ 0x000008c2, 0x0000 }, /* R2242 (0x8c2) - DRC1LMIX Input 2 Source */
{ 0x000008c3, 0x0080 }, /* R2243 (0x8c3) - DRC1LMIX Input 2 Volume */
{ 0x000008c4, 0x0000 }, /* R2244 (0x8c4) - DRC1LMIX Input 3 Source */
{ 0x000008c5, 0x0080 }, /* R2245 (0x8c5) - DRC1LMIX Input 3 Volume */
{ 0x000008c6, 0x0000 }, /* R2246 (0x8c6) - DRC1LMIX Input 4 Source */
{ 0x000008c7, 0x0080 }, /* R2247 (0x8c7) - DRC1LMIX Input 4 Volume */
{ 0x000008c8, 0x0000 }, /* R2248 (0x8c8) - DRC1RMIX Input 1 Source */
{ 0x000008c9, 0x0080 }, /* R2249 (0x8c9) - DRC1RMIX Input 1 Volume */
{ 0x000008ca, 0x0000 }, /* R2250 (0x8ca) - DRC1RMIX Input 2 Source */
{ 0x000008cb, 0x0080 }, /* R2251 (0x8cb) - DRC1RMIX Input 2 Volume */
{ 0x000008cc, 0x0000 }, /* R2252 (0x8cc) - DRC1RMIX Input 3 Source */
{ 0x000008cd, 0x0080 }, /* R2253 (0x8cd) - DRC1RMIX Input 3 Volume */
{ 0x000008ce, 0x0000 }, /* R2254 (0x8ce) - DRC1RMIX Input 4 Source */
{ 0x000008cf, 0x0080 }, /* R2255 (0x8cf) - DRC1RMIX Input 4 Volume */
{ 0x000008d0, 0x0000 }, /* R2256 (0x8d0) - DRC2LMIX Input 1 Source */
{ 0x000008d1, 0x0080 }, /* R2257 (0x8d1) - DRC2LMIX Input 1 Volume */
{ 0x000008d2, 0x0000 }, /* R2258 (0x8d2) - DRC2LMIX Input 2 Source */
{ 0x000008d3, 0x0080 }, /* R2259 (0x8d3) - DRC2LMIX Input 2 Volume */
{ 0x000008d4, 0x0000 }, /* R2260 (0x8d4) - DRC2LMIX Input 3 Source */
{ 0x000008d5, 0x0080 }, /* R2261 (0x8d5) - DRC2LMIX Input 3 Volume */
{ 0x000008d6, 0x0000 }, /* R2262 (0x8d6) - DRC2LMIX Input 4 Source */
{ 0x000008d7, 0x0080 }, /* R2263 (0x8d7) - DRC2LMIX Input 4 Volume */
{ 0x000008d8, 0x0000 }, /* R2264 (0x8d8) - DRC2RMIX Input 1 Source */
{ 0x000008d9, 0x0080 }, /* R2265 (0x8d9) - DRC2RMIX Input 1 Volume */
{ 0x000008da, 0x0000 }, /* R2266 (0x8da) - DRC2RMIX Input 2 Source */
{ 0x000008db, 0x0080 }, /* R2267 (0x8db) - DRC2RMIX Input 2 Volume */
{ 0x000008dc, 0x0000 }, /* R2268 (0x8dc) - DRC2RMIX Input 3 Source */
{ 0x000008dd, 0x0080 }, /* R2269 (0x8dd) - DRC2RMIX Input 3 Volume */
{ 0x000008de, 0x0000 }, /* R2270 (0x8de) - DRC2RMIX Input 4 Source */
{ 0x000008df, 0x0080 }, /* R2271 (0x8df) - DRC2RMIX Input 4 Volume */
{ 0x00000900, 0x0000 }, /* R2304 (0x900) - HPLP1MIX Input 1 Source */
{ 0x00000901, 0x0080 }, /* R2305 (0x901) - HPLP1MIX Input 1 Volume */
{ 0x00000902, 0x0000 }, /* R2306 (0x902) - HPLP1MIX Input 2 Source */
{ 0x00000903, 0x0080 }, /* R2307 (0x903) - HPLP1MIX Input 2 Volume */
{ 0x00000904, 0x0000 }, /* R2308 (0x904) - HPLP1MIX Input 3 Source */
{ 0x00000905, 0x0080 }, /* R2309 (0x905) - HPLP1MIX Input 3 Volume */
{ 0x00000906, 0x0000 }, /* R2310 (0x906) - HPLP1MIX Input 4 Source */
{ 0x00000907, 0x0080 }, /* R2311 (0x907) - HPLP1MIX Input 4 Volume */
{ 0x00000908, 0x0000 }, /* R2312 (0x908) - HPLP2MIX Input 1 Source */
{ 0x00000909, 0x0080 }, /* R2313 (0x909) - HPLP2MIX Input 1 Volume */
{ 0x0000090a, 0x0000 }, /* R2314 (0x90a) - HPLP2MIX Input 2 Source */
{ 0x0000090b, 0x0080 }, /* R2315 (0x90b) - HPLP2MIX Input 2 Volume */
{ 0x0000090c, 0x0000 }, /* R2316 (0x90c) - HPLP2MIX Input 3 Source */
{ 0x0000090d, 0x0080 }, /* R2317 (0x90d) - HPLP2MIX Input 3 Volume */
{ 0x0000090e, 0x0000 }, /* R2318 (0x90e) - HPLP2MIX Input 4 Source */
{ 0x0000090f, 0x0080 }, /* R2319 (0x90f) - HPLP2MIX Input 4 Volume */
{ 0x00000910, 0x0000 }, /* R2320 (0x910) - HPLP3MIX Input 1 Source */
{ 0x00000911, 0x0080 }, /* R2321 (0x911) - HPLP3MIX Input 1 Volume */
{ 0x00000912, 0x0000 }, /* R2322 (0x912) - HPLP3MIX Input 2 Source */
{ 0x00000913, 0x0080 }, /* R2323 (0x913) - HPLP3MIX Input 2 Volume */
{ 0x00000914, 0x0000 }, /* R2324 (0x914) - HPLP3MIX Input 3 Source */
{ 0x00000915, 0x0080 }, /* R2325 (0x915) - HPLP3MIX Input 3 Volume */
{ 0x00000916, 0x0000 }, /* R2326 (0x916) - HPLP3MIX Input 4 Source */
{ 0x00000917, 0x0080 }, /* R2327 (0x917) - HPLP3MIX Input 4 Volume */
{ 0x00000918, 0x0000 }, /* R2328 (0x918) - HPLP4MIX Input 1 Source */
{ 0x00000919, 0x0080 }, /* R2329 (0x919) - HPLP4MIX Input 1 Volume */
{ 0x0000091a, 0x0000 }, /* R2330 (0x91a) - HPLP4MIX Input 2 Source */
{ 0x0000091b, 0x0080 }, /* R2331 (0x91b) - HPLP4MIX Input 2 Volume */
{ 0x0000091c, 0x0000 }, /* R2332 (0x91c) - HPLP4MIX Input 3 Source */
{ 0x0000091d, 0x0080 }, /* R2333 (0x91d) - HPLP4MIX Input 3 Volume */
{ 0x0000091e, 0x0000 }, /* R2334 (0x91e) - HPLP4MIX Input 4 Source */
{ 0x0000091f, 0x0080 }, /* R2335 (0x91f) - HPLP4MIX Input 4 Volume */
{ 0x00000940, 0x0000 }, /* R2368 (0x940) - DSP1LMIX Input 1 Source */
{ 0x00000941, 0x0080 }, /* R2369 (0x941) - DSP1LMIX Input 1 Volume */
{ 0x00000942, 0x0000 }, /* R2370 (0x942) - DSP1LMIX Input 2 Source */
{ 0x00000943, 0x0080 }, /* R2371 (0x943) - DSP1LMIX Input 2 Volume */
{ 0x00000944, 0x0000 }, /* R2372 (0x944) - DSP1LMIX Input 3 Source */
{ 0x00000945, 0x0080 }, /* R2373 (0x945) - DSP1LMIX Input 3 Volume */
{ 0x00000946, 0x0000 }, /* R2374 (0x946) - DSP1LMIX Input 4 Source */
{ 0x00000947, 0x0080 }, /* R2375 (0x947) - DSP1LMIX Input 4 Volume */
{ 0x00000948, 0x0000 }, /* R2376 (0x948) - DSP1RMIX Input 1 Source */
{ 0x00000949, 0x0080 }, /* R2377 (0x949) - DSP1RMIX Input 1 Volume */
{ 0x0000094a, 0x0000 }, /* R2378 (0x94a) - DSP1RMIX Input 2 Source */
{ 0x0000094b, 0x0080 }, /* R2379 (0x94b) - DSP1RMIX Input 2 Volume */
{ 0x0000094c, 0x0000 }, /* R2380 (0x94c) - DSP1RMIX Input 3 Source */
{ 0x0000094d, 0x0080 }, /* R2381 (0x94d) - DSP1RMIX Input 3 Volume */
{ 0x0000094e, 0x0000 }, /* R2382 (0x94e) - DSP1RMIX Input 4 Source */
{ 0x0000094f, 0x0080 }, /* R2383 (0x94f) - DSP1RMIX Input 4 Volume */
{ 0x00000950, 0x0000 }, /* R2384 (0x950) - DSP1AUX1MIX Input 1 Source */
{ 0x00000958, 0x0000 }, /* R2392 (0x958) - DSP1AUX2MIX Input 1 Source */
{ 0x00000960, 0x0000 }, /* R2400 (0x960) - DSP1AUX3MIX Input 1 Source */
{ 0x00000968, 0x0000 }, /* R2408 (0x968) - DSP1AUX4MIX Input 1 Source */
{ 0x00000970, 0x0000 }, /* R2416 (0x970) - DSP1AUX5MIX Input 1 Source */
{ 0x00000978, 0x0000 }, /* R2424 (0x978) - DSP1AUX6MIX Input 1 Source */
{ 0x00000980, 0x0000 }, /* R2432 (0x980) - DSP2LMIX Input 1 Source */
{ 0x00000981, 0x0080 }, /* R2433 (0x981) - DSP2LMIX Input 1 Volume */
{ 0x00000982, 0x0000 }, /* R2434 (0x982) - DSP2LMIX Input 2 Source */
{ 0x00000983, 0x0080 }, /* R2435 (0x983) - DSP2LMIX Input 2 Volume */
{ 0x00000984, 0x0000 }, /* R2436 (0x984) - DSP2LMIX Input 3 Source */
{ 0x00000985, 0x0080 }, /* R2437 (0x985) - DSP2LMIX Input 3 Volume */
{ 0x00000986, 0x0000 }, /* R2438 (0x986) - DSP2LMIX Input 4 Source */
{ 0x00000987, 0x0080 }, /* R2439 (0x987) - DSP2LMIX Input 4 Volume */
{ 0x00000988, 0x0000 }, /* R2440 (0x988) - DSP2RMIX Input 1 Source */
{ 0x00000989, 0x0080 }, /* R2441 (0x989) - DSP2RMIX Input 1 Volume */
{ 0x0000098a, 0x0000 }, /* R2442 (0x98a) - DSP2RMIX Input 2 Source */
{ 0x0000098b, 0x0080 }, /* R2443 (0x98b) - DSP2RMIX Input 2 Volume */
{ 0x0000098c, 0x0000 }, /* R2444 (0x98c) - DSP2RMIX Input 3 Source */
{ 0x0000098d, 0x0080 }, /* R2445 (0x98d) - DSP2RMIX Input 3 Volume */
{ 0x0000098e, 0x0000 }, /* R2446 (0x98e) - DSP2RMIX Input 4 Source */
{ 0x0000098f, 0x0080 }, /* R2447 (0x98f) - DSP2RMIX Input 4 Volume */
{ 0x00000990, 0x0000 }, /* R2448 (0x990) - DSP2AUX1MIX Input 1 Source */
{ 0x00000998, 0x0000 }, /* R2456 (0x998) - DSP2AUX2MIX Input 1 Source */
{ 0x000009a0, 0x0000 }, /* R2464 (0x9a0) - DSP2AUX3MIX Input 1 Source */
{ 0x000009a8, 0x0000 }, /* R2472 (0x9a8) - DSP2AUX4MIX Input 1 Source */
{ 0x000009b0, 0x0000 }, /* R2480 (0x9b0) - DSP2AUX5MIX Input 1 Source */
{ 0x000009b8, 0x0000 }, /* R2488 (0x9b8) - DSP2AUX6MIX Input 1 Source */
{ 0x000009c0, 0x0000 }, /* R2496 (0x9c0) - DSP3LMIX Input 1 Source */
{ 0x000009c1, 0x0080 }, /* R2497 (0x9c1) - DSP3LMIX Input 1 Volume */
{ 0x000009c2, 0x0000 }, /* R2498 (0x9c2) - DSP3LMIX Input 2 Source */
{ 0x000009c3, 0x0080 }, /* R2499 (0x9c3) - DSP3LMIX Input 2 Volume */
{ 0x000009c4, 0x0000 }, /* R2500 (0x9c4) - DSP3LMIX Input 3 Source */
{ 0x000009c5, 0x0080 }, /* R2501 (0x9c5) - DSP3LMIX Input 3 Volume */
{ 0x000009c6, 0x0000 }, /* R2502 (0x9c6) - DSP3LMIX Input 4 Source */
{ 0x000009c7, 0x0080 }, /* R2503 (0x9c7) - DSP3LMIX Input 4 Volume */
{ 0x000009c8, 0x0000 }, /* R2504 (0x9c8) - DSP3RMIX Input 1 Source */
{ 0x000009c9, 0x0080 }, /* R2505 (0x9c9) - DSP3RMIX Input 1 Volume */
{ 0x000009ca, 0x0000 }, /* R2506 (0x9ca) - DSP3RMIX Input 2 Source */
{ 0x000009cb, 0x0080 }, /* R2507 (0x9cb) - DSP3RMIX Input 2 Volume */
{ 0x000009cc, 0x0000 }, /* R2508 (0x9cc) - DSP3RMIX Input 3 Source */
{ 0x000009cd, 0x0080 }, /* R2509 (0x9cd) - DSP3RMIX Input 3 Volume */
{ 0x000009ce, 0x0000 }, /* R2510 (0x9ce) - DSP3RMIX Input 4 Source */
{ 0x000009cf, 0x0080 }, /* R2511 (0x9cf) - DSP3RMIX Input 4 Volume */
{ 0x000009d0, 0x0000 }, /* R2512 (0x9d0) - DSP3AUX1MIX Input 1 Source */
{ 0x000009d8, 0x0000 }, /* R2520 (0x9d8) - DSP3AUX2MIX Input 1 Source */
{ 0x000009e0, 0x0000 }, /* R2528 (0x9e0) - DSP3AUX3MIX Input 1 Source */
{ 0x000009e8, 0x0000 }, /* R2536 (0x9e8) - DSP3AUX4MIX Input 1 Source */
{ 0x000009f0, 0x0000 }, /* R2544 (0x9f0) - DSP3AUX5MIX Input 1 Source */
{ 0x000009f8, 0x0000 }, /* R2552 (0x9f8) - DSP3AUX6MIX Input 1 Source */
{ 0x00000b00, 0x0000 }, /* R2816 (0xb00) - ISRC1DEC1MIX Input 1 Source*/
{ 0x00000b08, 0x0000 }, /* R2824 (0xb08) - ISRC1DEC2MIX Input 1 Source*/
{ 0x00000b10, 0x0000 }, /* R2832 (0xb10) - ISRC1DEC3MIX Input 1 Source*/
{ 0x00000b18, 0x0000 }, /* R2840 (0xb18) - ISRC1DEC4MIX Input 1 Source*/
{ 0x00000b20, 0x0000 }, /* R2848 (0xb20) - ISRC1INT1MIX Input 1 Source*/
{ 0x00000b28, 0x0000 }, /* R2856 (0xb28) - ISRC1INT2MIX Input 1 Source*/
{ 0x00000b30, 0x0000 }, /* R2864 (0xb30) - ISRC1INT3MIX Input 1 Source*/
{ 0x00000b38, 0x0000 }, /* R2872 (0xb38) - ISRC1INT4MIX Input 1 Source*/
{ 0x00000b40, 0x0000 }, /* R2880 (0xb40) - ISRC2DEC1MIX Input 1 Source*/
{ 0x00000b48, 0x0000 }, /* R2888 (0xb48) - ISRC2DEC2MIX Input 1 Source*/
{ 0x00000b50, 0x0000 }, /* R2896 (0xb50) - ISRC2DEC3MIX Input 1 Source*/
{ 0x00000b58, 0x0000 }, /* R2904 (0xb58) - ISRC2DEC4MIX Input 1 Source*/
{ 0x00000b60, 0x0000 }, /* R2912 (0xb60) - ISRC2INT1MIX Input 1 Source*/
{ 0x00000b68, 0x0000 }, /* R2920 (0xb68) - ISRC2INT2MIX Input 1 Source*/
{ 0x00000b70, 0x0000 }, /* R2928 (0xb70) - ISRC2INT3MIX Input 1 Source*/
{ 0x00000b78, 0x0000 }, /* R2936 (0xb78) - ISRC2INT4MIX Input 1 Source*/
{ 0x00000e00, 0x0000 }, /* R3584 (0xe00) - FX Ctrl1 */
{ 0x00000e10, 0x6318 }, /* R3600 (0xe10) - EQ1_1 */
{ 0x00000e11, 0x6300 }, /* R3601 (0xe11) - EQ1_2 */
{ 0x00000e12, 0x0fc8 }, /* R3602 (0xe12) - EQ1_3 */
{ 0x00000e13, 0x03fe }, /* R3603 (0xe13) - EQ1_4 */
{ 0x00000e14, 0x00e0 }, /* R3604 (0xe14) - EQ1_5 */
{ 0x00000e15, 0x1ec4 }, /* R3605 (0xe15) - EQ1_6 */
{ 0x00000e16, 0xf136 }, /* R3606 (0xe16) - EQ1_7 */
{ 0x00000e17, 0x0409 }, /* R3607 (0xe17) - EQ1_8 */
{ 0x00000e18, 0x04cc }, /* R3608 (0xe18) - EQ1_9 */
{ 0x00000e19, 0x1c9b }, /* R3609 (0xe19) - EQ1_10 */
{ 0x00000e1a, 0xf337 }, /* R3610 (0xe1a) - EQ1_11 */
{ 0x00000e1b, 0x040b }, /* R3611 (0xe1b) - EQ1_12 */
{ 0x00000e1c, 0x0cbb }, /* R3612 (0xe1c) - EQ1_13 */
{ 0x00000e1d, 0x16f8 }, /* R3613 (0xe1d) - EQ1_14 */
{ 0x00000e1e, 0xf7d9 }, /* R3614 (0xe1e) - EQ1_15 */
{ 0x00000e1f, 0x040a }, /* R3615 (0xe1f) - EQ1_16 */
{ 0x00000e20, 0x1f14 }, /* R3616 (0xe20) - EQ1_17 */
{ 0x00000e21, 0x058c }, /* R3617 (0xe21) - EQ1_18 */
{ 0x00000e22, 0x0563 }, /* R3618 (0xe22) - EQ1_19 */
{ 0x00000e23, 0x4000 }, /* R3619 (0xe23) - EQ1_20 */
{ 0x00000e24, 0x0b75 }, /* R3620 (0xe24) - EQ1_21 */
{ 0x00000e26, 0x6318 }, /* R3622 (0xe26) - EQ2_1 */
{ 0x00000e27, 0x6300 }, /* R3623 (0xe27) - EQ2_2 */
{ 0x00000e28, 0x0fc8 }, /* R3624 (0xe28) - EQ2_3 */
{ 0x00000e29, 0x03fe }, /* R3625 (0xe29) - EQ2_4 */
{ 0x00000e2a, 0x00e0 }, /* R3626 (0xe2a) - EQ2_5 */
{ 0x00000e2b, 0x1ec4 }, /* R3627 (0xe2b) - EQ2_6 */
{ 0x00000e2c, 0xf136 }, /* R3628 (0xe2c) - EQ2_7 */
{ 0x00000e2d, 0x0409 }, /* R3629 (0xe2d) - EQ2_8 */
{ 0x00000e2e, 0x04cc }, /* R3630 (0xe2e) - EQ2_9 */
{ 0x00000e2f, 0x1c9b }, /* R3631 (0xe2f) - EQ2_10 */
{ 0x00000e30, 0xf337 }, /* R3632 (0xe30) - EQ2_11 */
{ 0x00000e31, 0x040b }, /* R3633 (0xe31) - EQ2_12 */
{ 0x00000e32, 0x0cbb }, /* R3634 (0xe32) - EQ2_13 */
{ 0x00000e33, 0x16f8 }, /* R3635 (0xe33) - EQ2_14 */
{ 0x00000e34, 0xf7d9 }, /* R3636 (0xe34) - EQ2_15 */
{ 0x00000e35, 0x040a }, /* R3637 (0xe35) - EQ2_16 */
{ 0x00000e36, 0x1f14 }, /* R3638 (0xe36) - EQ2_17 */
{ 0x00000e37, 0x058c }, /* R3639 (0xe37) - EQ2_18 */
{ 0x00000e38, 0x0563 }, /* R3640 (0xe38) - EQ2_19 */
{ 0x00000e39, 0x4000 }, /* R3641 (0xe39) - EQ2_20 */
{ 0x00000e3a, 0x0b75 }, /* R3642 (0xe3a) - EQ2_21 */
{ 0x00000e3c, 0x6318 }, /* R3644 (0xe3c) - EQ3_1 */
{ 0x00000e3d, 0x6300 }, /* R3645 (0xe3d) - EQ3_2 */
{ 0x00000e3e, 0x0fc8 }, /* R3646 (0xe3e) - EQ3_3 */
{ 0x00000e3f, 0x03fe }, /* R3647 (0xe3f) - EQ3_4 */
{ 0x00000e40, 0x00e0 }, /* R3648 (0xe40) - EQ3_5 */
{ 0x00000e41, 0x1ec4 }, /* R3649 (0xe41) - EQ3_6 */
{ 0x00000e42, 0xf136 }, /* R3650 (0xe42) - EQ3_7 */
{ 0x00000e43, 0x0409 }, /* R3651 (0xe43) - EQ3_8 */
{ 0x00000e44, 0x04cc }, /* R3652 (0xe44) - EQ3_9 */
{ 0x00000e45, 0x1c9b }, /* R3653 (0xe45) - EQ3_10 */
{ 0x00000e46, 0xf337 }, /* R3654 (0xe46) - EQ3_11 */
{ 0x00000e47, 0x040b }, /* R3655 (0xe47) - EQ3_12 */
{ 0x00000e48, 0x0cbb }, /* R3656 (0xe48) - EQ3_13 */
{ 0x00000e49, 0x16f8 }, /* R3657 (0xe49) - EQ3_14 */
{ 0x00000e4a, 0xf7d9 }, /* R3658 (0xe4a) - EQ3_15 */
{ 0x00000e4b, 0x040a }, /* R3659 (0xe4b) - EQ3_16 */
{ 0x00000e4c, 0x1f14 }, /* R3660 (0xe4c) - EQ3_17 */
{ 0x00000e4d, 0x058c }, /* R3661 (0xe4d) - EQ3_18 */
{ 0x00000e4e, 0x0563 }, /* R3662 (0xe4e) - EQ3_19 */
{ 0x00000e4f, 0x4000 }, /* R3663 (0xe4f) - EQ3_20 */
{ 0x00000e50, 0x0b75 }, /* R3664 (0xe50) - EQ3_21 */
{ 0x00000e52, 0x6318 }, /* R3666 (0xe52) - EQ4_1 */
{ 0x00000e53, 0x6300 }, /* R3667 (0xe53) - EQ4_2 */
{ 0x00000e54, 0x0fc8 }, /* R3668 (0xe54) - EQ4_3 */
{ 0x00000e55, 0x03fe }, /* R3669 (0xe55) - EQ4_4 */
{ 0x00000e56, 0x00e0 }, /* R3670 (0xe56) - EQ4_5 */
{ 0x00000e57, 0x1ec4 }, /* R3671 (0xe57) - EQ4_6 */
{ 0x00000e58, 0xf136 }, /* R3672 (0xe58) - EQ4_7 */
{ 0x00000e59, 0x0409 }, /* R3673 (0xe59) - EQ4_8 */
{ 0x00000e5a, 0x04cc }, /* R3674 (0xe5a) - EQ4_9 */
{ 0x00000e5b, 0x1c9b }, /* R3675 (0xe5b) - EQ4_10 */
{ 0x00000e5c, 0xf337 }, /* R3676 (0xe5c) - EQ4_11 */
{ 0x00000e5d, 0x040b }, /* R3677 (0xe5d) - EQ4_12 */
{ 0x00000e5e, 0x0cbb }, /* R3678 (0xe5e) - EQ4_13 */
{ 0x00000e5f, 0x16f8 }, /* R3679 (0xe5f) - EQ4_14 */
{ 0x00000e60, 0xf7d9 }, /* R3680 (0xe60) - EQ4_15 */
{ 0x00000e61, 0x040a }, /* R3681 (0xe61) - EQ4_16 */
{ 0x00000e62, 0x1f14 }, /* R3682 (0xe62) - EQ4_17 */
{ 0x00000e63, 0x058c }, /* R3683 (0xe63) - EQ4_18 */
{ 0x00000e64, 0x0563 }, /* R3684 (0xe64) - EQ4_19 */
{ 0x00000e65, 0x4000 }, /* R3685 (0xe65) - EQ4_20 */
{ 0x00000e66, 0x0b75 }, /* R3686 (0xe66) - EQ4_21 */
{ 0x00000e80, 0x0018 }, /* R3712 (0xe80) - DRC1 ctrl1 */
{ 0x00000e81, 0x0933 }, /* R3713 (0xe81) - DRC1 ctrl2 */
{ 0x00000e82, 0x0018 }, /* R3714 (0xe82) - DRC1 ctrl3 */
{ 0x00000e83, 0x0000 }, /* R3715 (0xe83) - DRC1 ctrl4 */
{ 0x00000e84, 0x0000 }, /* R3716 (0xe84) - DRC1 ctrl5 */
{ 0x00000e88, 0x0018 }, /* R3720 (0xe88) - DRC2 ctrl1 */
{ 0x00000e89, 0x0933 }, /* R3721 (0xe89) - DRC2 ctrl2 */
{ 0x00000e8a, 0x0018 }, /* R3722 (0xe8a) - DRC2 ctrl3 */
{ 0x00000e8b, 0x0000 }, /* R3723 (0xe8b) - DRC2 ctrl4 */
{ 0x00000e8c, 0x0000 }, /* R3724 (0xe8c) - DRC2 ctrl5 */
{ 0x00000ec0, 0x0000 }, /* R3776 (0xec0) - HPLPF1_1 */
{ 0x00000ec1, 0x0000 }, /* R3777 (0xec1) - HPLPF1_2 */
{ 0x00000ec4, 0x0000 }, /* R3780 (0xec4) - HPLPF2_1 */
{ 0x00000ec5, 0x0000 }, /* R3781 (0xec5) - HPLPF2_2 */
{ 0x00000ec8, 0x0000 }, /* R3784 (0xec8) - HPLPF3_1 */
{ 0x00000ec9, 0x0000 }, /* R3785 (0xec9) - HPLPF3_2 */
{ 0x00000ecc, 0x0000 }, /* R3788 (0xecc) - HPLPF4_1 */
{ 0x00000ecd, 0x0000 }, /* R3789 (0xecd) - HPLPF4_2 */
{ 0x00000ef0, 0x0000 }, /* R3824 (0xef0) - ISRC 1 CTRL 1 */
{ 0x00000ef1, 0x0001 }, /* R3825 (0xef1) - ISRC 1 CTRL 2 */
{ 0x00000ef2, 0x0000 }, /* R3826 (0xef2) - ISRC 1 CTRL 3 */
{ 0x00000ef3, 0x0000 }, /* R3827 (0xef3) - ISRC 2 CTRL 1 */
{ 0x00000ef4, 0x0001 }, /* R3828 (0xef4) - ISRC 2 CTRL 2 */
{ 0x00000ef5, 0x0000 }, /* R3829 (0xef5) - ISRC 2 CTRL 3 */
{ 0x00001300, 0x0000 }, /* R4864 (0x1300) - DAC Comp 1 */
{ 0x00001302, 0x0000 }, /* R4866 (0x1302) - DAC Comp 2 */
{ 0x00001380, 0x0000 }, /* R4992 (0x1380) - FRF Coefficient 1L 1 */
{ 0x00001381, 0x0000 }, /* R4993 (0x1381) - FRF Coefficient 1L 2 */
{ 0x00001382, 0x0000 }, /* R4994 (0x1382) - FRF Coefficient 1L 3 */
{ 0x00001383, 0x0000 }, /* R4995 (0x1383) - FRF Coefficient 1L 4 */
{ 0x00001390, 0x0000 }, /* R5008 (0x1390) - FRF Coefficient 1R 1 */
{ 0x00001391, 0x0000 }, /* R5009 (0x1391) - FRF Coefficient 1R 2 */
{ 0x00001392, 0x0000 }, /* R5010 (0x1392) - FRF Coefficient 1R 3 */
{ 0x00001393, 0x0000 }, /* R5011 (0x1393) - FRF Coefficient 1R 4 */
{ 0x000013a0, 0x0000 }, /* R5024 (0x13a0) - FRF Coefficient 4L 1 */
{ 0x000013a1, 0x0000 }, /* R5025 (0x13a1) - FRF Coefficient 4L 2 */
{ 0x000013a2, 0x0000 }, /* R5026 (0x13a2) - FRF Coefficient 4L 3 */
{ 0x000013a3, 0x0000 }, /* R5027 (0x13a3) - FRF Coefficient 4L 4 */
{ 0x000013b0, 0x0000 }, /* R5040 (0x13b0) - FRF Coefficient 5L 1 */
{ 0x000013b1, 0x0000 }, /* R5041 (0x13b1) - FRF Coefficient 5L 2 */
{ 0x000013b2, 0x0000 }, /* R5042 (0x13b2) - FRF Coefficient 5L 3 */
{ 0x000013b3, 0x0000 }, /* R5043 (0x13b3) - FRF Coefficient 5L 4 */
{ 0x000013c0, 0x0000 }, /* R5040 (0x13c0) - FRF Coefficient 5R 1 */
{ 0x000013c1, 0x0000 }, /* R5041 (0x13c1) - FRF Coefficient 5R 2 */
{ 0x000013c2, 0x0000 }, /* R5042 (0x13c2) - FRF Coefficient 5R 3 */
{ 0x000013c3, 0x0000 }, /* R5043 (0x13c3) - FRF Coefficient 5R 4 */
{ 0x00001700, 0x2001 }, /* R5888 (0x1700) - GPIO1 Control 1 */
{ 0x00001701, 0xf000 }, /* R5889 (0x1701) - GPIO1 Control 2 */
{ 0x00001702, 0x2001 }, /* R5890 (0x1702) - GPIO2 Control 1 */
{ 0x00001703, 0xf000 }, /* R5891 (0x1703) - GPIO2 Control 2 */
{ 0x00001704, 0x2001 }, /* R5892 (0x1704) - GPIO3 Control 1 */
{ 0x00001705, 0xf000 }, /* R5893 (0x1705) - GPIO3 Control 2 */
{ 0x00001706, 0x2001 }, /* R5894 (0x1706) - GPIO4 Control 1 */
{ 0x00001707, 0xf000 }, /* R5895 (0x1707) - GPIO4 Control 2 */
{ 0x00001708, 0x2001 }, /* R5896 (0x1708) - GPIO5 Control 1 */
{ 0x00001709, 0xf000 }, /* R5897 (0x1709) - GPIO5 Control 2 */
{ 0x0000170a, 0x2001 }, /* R5898 (0x170a) - GPIO6 Control 1 */
{ 0x0000170b, 0xf000 }, /* R5899 (0x170b) - GPIO6 Control 2 */
{ 0x0000170c, 0x2001 }, /* R5900 (0x170c) - GPIO7 Control 1 */
{ 0x0000170d, 0xf000 }, /* R5901 (0x170d) - GPIO7 Control 2 */
{ 0x0000170e, 0x2001 }, /* R5902 (0x170e) - GPIO8 Control 1 */
{ 0x0000170f, 0xf000 }, /* R5903 (0x170f) - GPIO8 Control 2 */
{ 0x00001710, 0x2001 }, /* R5904 (0x1710) - GPIO9 Control 1 */
{ 0x00001711, 0xf000 }, /* R5905 (0x1711) - GPIO9 Control 2 */
{ 0x00001712, 0x2001 }, /* R5906 (0x1712) - GPIO10 Control 1 */
{ 0x00001713, 0xf000 }, /* R5907 (0x1713) - GPIO10 Control 2 */
{ 0x00001714, 0x2001 }, /* R5908 (0x1714) - GPIO11 Control 1 */
{ 0x00001715, 0xf000 }, /* R5909 (0x1715) - GPIO11 Control 2 */
{ 0x00001716, 0x2001 }, /* R5910 (0x1716) - GPIO12 Control 1 */
{ 0x00001717, 0xf000 }, /* R5911 (0x1717) - GPIO12 Control 2 */
{ 0x00001718, 0x2001 }, /* R5912 (0x1718) - GPIO13 Control 1 */
{ 0x00001719, 0xf000 }, /* R5913 (0x1719) - GPIO13 Control 2 */
{ 0x0000171a, 0x2001 }, /* R5914 (0x171a) - GPIO14 Control 1 */
{ 0x0000171b, 0xf000 }, /* R5915 (0x171b) - GPIO14 Control 2 */
{ 0x0000171c, 0x2001 }, /* R5916 (0x171c) - GPIO15 Control 1 */
{ 0x0000171d, 0xf000 }, /* R5917 (0x171d) - GPIO15 Control 2 */
{ 0x0000171e, 0x2001 }, /* R5918 (0x171e) - GPIO16 Control 1 */
{ 0x0000171f, 0xf000 }, /* R5919 (0x171f) - GPIO16 Control 2 */
{ 0x00001840, 0xffff }, /* R6208 (0x1840) - IRQ1 Mask 1 */
{ 0x00001841, 0xffff }, /* R6209 (0x1841) - IRQ1 Mask 2 */
{ 0x00001842, 0xffff }, /* R6210 (0x1842) - IRQ1 Mask 3 */
{ 0x00001843, 0xffff }, /* R6211 (0x1843) - IRQ1 Mask 4 */
{ 0x00001844, 0xffff }, /* R6212 (0x1844) - IRQ1 Mask 5 */
{ 0x00001845, 0xffff }, /* R6213 (0x1845) - IRQ1 Mask 6 */
{ 0x00001846, 0xffff }, /* R6214 (0x1846) - IRQ1 Mask 7 */
{ 0x00001847, 0xffff }, /* R6215 (0x1847) - IRQ1 Mask 8 */
{ 0x00001848, 0xffff }, /* R6216 (0x1848) - IRQ1 Mask 9 */
{ 0x00001849, 0xffff }, /* R6217 (0x1849) - IRQ1 Mask 10 */
{ 0x0000184a, 0xffff }, /* R6218 (0x184a) - IRQ1 Mask 11 */
{ 0x0000184b, 0xffff }, /* R6219 (0x184b) - IRQ1 Mask 12 */
{ 0x0000184c, 0xffff }, /* R6220 (0x184c) - IRQ1 Mask 13 */
{ 0x0000184d, 0xffff }, /* R6221 (0x184d) - IRQ1 Mask 14 */
{ 0x0000184e, 0xffff }, /* R6222 (0x184e) - IRQ1 Mask 15 */
{ 0x0000184f, 0xffff }, /* R6223 (0x184f) - IRQ1 Mask 16 */
{ 0x00001850, 0xffff }, /* R6224 (0x1850) - IRQ1 Mask 17 */
{ 0x00001851, 0xffff }, /* R6225 (0x1851) - IRQ1 Mask 18 */
{ 0x00001852, 0xffff }, /* R6226 (0x1852) - IRQ1 Mask 19 */
{ 0x00001853, 0xffff }, /* R6227 (0x1853) - IRQ1 Mask 20 */
{ 0x00001854, 0xffff }, /* R6228 (0x1854) - IRQ1 Mask 21 */
{ 0x00001855, 0xffff }, /* R6229 (0x1855) - IRQ1 Mask 22 */
{ 0x00001856, 0xffff }, /* R6230 (0x1856) - IRQ1 Mask 23 */
{ 0x00001857, 0xffff }, /* R6231 (0x1857) - IRQ1 Mask 24 */
{ 0x00001858, 0xffff }, /* R6232 (0x1858) - IRQ1 Mask 25 */
{ 0x00001859, 0xffff }, /* R6233 (0x1859) - IRQ1 Mask 26 */
{ 0x0000185a, 0xffff }, /* R6234 (0x185a) - IRQ1 Mask 27 */
{ 0x0000185b, 0xffff }, /* R6235 (0x185b) - IRQ1 Mask 28 */
{ 0x0000185c, 0xffff }, /* R6236 (0x185c) - IRQ1 Mask 29 */
{ 0x0000185d, 0xffff }, /* R6237 (0x185d) - IRQ1 Mask 30 */
{ 0x0000185e, 0xffff }, /* R6238 (0x185e) - IRQ1 Mask 31 */
{ 0x0000185f, 0xffff }, /* R6239 (0x185f) - IRQ1 Mask 32 */
{ 0x00001860, 0xffff }, /* R6240 (0x1860) - IRQ1 Mask 33 */
{ 0x00001a06, 0x0000 }, /* R6662 (0x1a06) - Interrupt Debounce 7 */
{ 0x00001a80, 0x4400 }, /* R6784 (0x1a80) - IRQ1 CTRL */
};
static bool cs47l35_is_adsp_memory(unsigned int reg)
{
switch (reg) {
case 0x080000 ... 0x085ffe:
case 0x0a0000 ... 0x0a7ffe:
case 0x0c0000 ... 0x0c1ffe:
case 0x0e0000 ... 0x0e1ffe:
case 0x100000 ... 0x10effe:
case 0x120000 ... 0x12bffe:
case 0x136000 ... 0x137ffe:
case 0x140000 ... 0x14bffe:
case 0x160000 ... 0x161ffe:
case 0x180000 ... 0x18effe:
case 0x1a0000 ... 0x1b1ffe:
case 0x1b6000 ... 0x1b7ffe:
case 0x1c0000 ... 0x1cbffe:
case 0x1e0000 ... 0x1e1ffe:
return true;
default:
return false;
}
}
static bool cs47l35_16bit_readable_register(struct device *dev,
unsigned int reg)
{
switch (reg) {
case MADERA_SOFTWARE_RESET:
case MADERA_HARDWARE_REVISION:
case MADERA_WRITE_SEQUENCER_CTRL_0:
case MADERA_WRITE_SEQUENCER_CTRL_1:
case MADERA_WRITE_SEQUENCER_CTRL_2:
case MADERA_TONE_GENERATOR_1:
case MADERA_TONE_GENERATOR_2:
case MADERA_TONE_GENERATOR_3:
case MADERA_TONE_GENERATOR_4:
case MADERA_TONE_GENERATOR_5:
case MADERA_PWM_DRIVE_1:
case MADERA_PWM_DRIVE_2:
case MADERA_PWM_DRIVE_3:
case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_1:
case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_2:
case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_3:
case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_4:
case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_1:
case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2:
case MADERA_HAPTICS_CONTROL_1:
case MADERA_HAPTICS_CONTROL_2:
case MADERA_HAPTICS_PHASE_1_INTENSITY:
case MADERA_HAPTICS_PHASE_1_DURATION:
case MADERA_HAPTICS_PHASE_2_INTENSITY:
case MADERA_HAPTICS_PHASE_2_DURATION:
case MADERA_HAPTICS_PHASE_3_INTENSITY:
case MADERA_HAPTICS_PHASE_3_DURATION:
case MADERA_HAPTICS_STATUS:
case MADERA_COMFORT_NOISE_GENERATOR:
case MADERA_CLOCK_32K_1:
case MADERA_SYSTEM_CLOCK_1:
case MADERA_SAMPLE_RATE_1:
case MADERA_SAMPLE_RATE_2:
case MADERA_SAMPLE_RATE_3:
case MADERA_SAMPLE_RATE_1_STATUS:
case MADERA_SAMPLE_RATE_2_STATUS:
case MADERA_SAMPLE_RATE_3_STATUS:
case MADERA_DSP_CLOCK_1:
case MADERA_DSP_CLOCK_2:
case MADERA_OUTPUT_SYSTEM_CLOCK:
case MADERA_OUTPUT_ASYNC_CLOCK:
case MADERA_RATE_ESTIMATOR_1:
case MADERA_RATE_ESTIMATOR_2:
case MADERA_RATE_ESTIMATOR_3:
case MADERA_RATE_ESTIMATOR_4:
case MADERA_RATE_ESTIMATOR_5:
case MADERA_FLL1_CONTROL_1:
case MADERA_FLL1_CONTROL_2:
case MADERA_FLL1_CONTROL_3:
case MADERA_FLL1_CONTROL_4:
case MADERA_FLL1_CONTROL_5:
case MADERA_FLL1_CONTROL_6:
case MADERA_FLL1_CONTROL_7:
case MADERA_FLL1_EFS_2:
case MADERA_FLL1_LOOP_FILTER_TEST_1:
case CS47L35_FLL1_SYNCHRONISER_1:
case CS47L35_FLL1_SYNCHRONISER_2:
case CS47L35_FLL1_SYNCHRONISER_3:
case CS47L35_FLL1_SYNCHRONISER_4:
case CS47L35_FLL1_SYNCHRONISER_5:
case CS47L35_FLL1_SYNCHRONISER_6:
case CS47L35_FLL1_SYNCHRONISER_7:
case CS47L35_FLL1_SPREAD_SPECTRUM:
case CS47L35_FLL1_GPIO_CLOCK:
case MADERA_MIC_CHARGE_PUMP_1:
case MADERA_HP_CHARGE_PUMP_8:
case MADERA_LDO2_CONTROL_1:
case MADERA_MIC_BIAS_CTRL_1:
case MADERA_MIC_BIAS_CTRL_2:
case MADERA_MIC_BIAS_CTRL_5:
case MADERA_MIC_BIAS_CTRL_6:
case MADERA_HP_CTRL_1L:
case MADERA_HP_CTRL_1R:
case MADERA_DCS_HP1L_CONTROL:
case MADERA_DCS_HP1R_CONTROL:
case MADERA_EDRE_HP_STEREO_CONTROL:
case MADERA_ACCESSORY_DETECT_MODE_1:
case MADERA_HEADPHONE_DETECT_1:
case MADERA_HEADPHONE_DETECT_2:
case MADERA_HEADPHONE_DETECT_3:
case MADERA_HEADPHONE_DETECT_5:
case MADERA_MICD_CLAMP_CONTROL:
case MADERA_MIC_DETECT_1_CONTROL_1:
case MADERA_MIC_DETECT_1_CONTROL_2:
case MADERA_MIC_DETECT_1_CONTROL_3:
case MADERA_MIC_DETECT_1_LEVEL_1:
case MADERA_MIC_DETECT_1_LEVEL_2:
case MADERA_MIC_DETECT_1_LEVEL_3:
case MADERA_MIC_DETECT_1_LEVEL_4:
case MADERA_MIC_DETECT_1_CONTROL_4:
case MADERA_GP_SWITCH_1:
case MADERA_JACK_DETECT_ANALOGUE:
case MADERA_INPUT_ENABLES:
case MADERA_INPUT_ENABLES_STATUS:
case MADERA_INPUT_RATE:
case MADERA_INPUT_VOLUME_RAMP:
case MADERA_HPF_CONTROL:
case MADERA_IN1L_CONTROL:
case MADERA_ADC_DIGITAL_VOLUME_1L:
case MADERA_DMIC1L_CONTROL:
case MADERA_IN1R_CONTROL:
case MADERA_ADC_DIGITAL_VOLUME_1R:
case MADERA_DMIC1R_CONTROL:
case MADERA_IN2L_CONTROL:
case MADERA_ADC_DIGITAL_VOLUME_2L:
case MADERA_DMIC2L_CONTROL:
case MADERA_IN2R_CONTROL:
case MADERA_ADC_DIGITAL_VOLUME_2R:
case MADERA_DMIC2R_CONTROL:
case MADERA_OUTPUT_ENABLES_1:
case MADERA_OUTPUT_STATUS_1:
case MADERA_RAW_OUTPUT_STATUS_1:
case MADERA_OUTPUT_RATE_1:
case MADERA_OUTPUT_VOLUME_RAMP:
case MADERA_OUTPUT_PATH_CONFIG_1L:
case MADERA_DAC_DIGITAL_VOLUME_1L:
case MADERA_NOISE_GATE_SELECT_1L:
case MADERA_OUTPUT_PATH_CONFIG_1R:
case MADERA_DAC_DIGITAL_VOLUME_1R:
case MADERA_NOISE_GATE_SELECT_1R:
case MADERA_OUTPUT_PATH_CONFIG_4L:
case MADERA_DAC_DIGITAL_VOLUME_4L:
case MADERA_NOISE_GATE_SELECT_4L:
case MADERA_OUTPUT_PATH_CONFIG_5L:
case MADERA_DAC_DIGITAL_VOLUME_5L:
case MADERA_NOISE_GATE_SELECT_5L:
case MADERA_OUTPUT_PATH_CONFIG_5R:
case MADERA_DAC_DIGITAL_VOLUME_5R:
case MADERA_NOISE_GATE_SELECT_5R:
case MADERA_DRE_ENABLE:
case MADERA_EDRE_ENABLE:
case MADERA_EDRE_MANUAL:
case MADERA_DAC_AEC_CONTROL_1:
case MADERA_NOISE_GATE_CONTROL:
case MADERA_PDM_SPK1_CTRL_1:
case MADERA_PDM_SPK1_CTRL_2:
case MADERA_HP1_SHORT_CIRCUIT_CTRL:
case MADERA_HP_TEST_CTRL_5:
case MADERA_HP_TEST_CTRL_6:
case MADERA_AIF1_BCLK_CTRL:
case MADERA_AIF1_TX_PIN_CTRL:
case MADERA_AIF1_RX_PIN_CTRL:
case MADERA_AIF1_RATE_CTRL:
case MADERA_AIF1_FORMAT:
case MADERA_AIF1_RX_BCLK_RATE:
case MADERA_AIF1_FRAME_CTRL_1:
case MADERA_AIF1_FRAME_CTRL_2:
case MADERA_AIF1_FRAME_CTRL_3:
case MADERA_AIF1_FRAME_CTRL_4:
case MADERA_AIF1_FRAME_CTRL_5:
case MADERA_AIF1_FRAME_CTRL_6:
case MADERA_AIF1_FRAME_CTRL_7:
case MADERA_AIF1_FRAME_CTRL_8:
case MADERA_AIF1_FRAME_CTRL_11:
case MADERA_AIF1_FRAME_CTRL_12:
case MADERA_AIF1_FRAME_CTRL_13:
case MADERA_AIF1_FRAME_CTRL_14:
case MADERA_AIF1_FRAME_CTRL_15:
case MADERA_AIF1_FRAME_CTRL_16:
case MADERA_AIF1_TX_ENABLES:
case MADERA_AIF1_RX_ENABLES:
case MADERA_AIF2_BCLK_CTRL:
case MADERA_AIF2_TX_PIN_CTRL:
case MADERA_AIF2_RX_PIN_CTRL:
case MADERA_AIF2_RATE_CTRL:
case MADERA_AIF2_FORMAT:
case MADERA_AIF2_RX_BCLK_RATE:
case MADERA_AIF2_FRAME_CTRL_1:
case MADERA_AIF2_FRAME_CTRL_2:
case MADERA_AIF2_FRAME_CTRL_3:
case MADERA_AIF2_FRAME_CTRL_4:
case MADERA_AIF2_FRAME_CTRL_11:
case MADERA_AIF2_FRAME_CTRL_12:
case MADERA_AIF2_TX_ENABLES:
case MADERA_AIF2_RX_ENABLES:
case MADERA_AIF3_BCLK_CTRL:
case MADERA_AIF3_TX_PIN_CTRL:
case MADERA_AIF3_RX_PIN_CTRL:
case MADERA_AIF3_RATE_CTRL:
case MADERA_AIF3_FORMAT:
case MADERA_AIF3_RX_BCLK_RATE:
case MADERA_AIF3_FRAME_CTRL_1:
case MADERA_AIF3_FRAME_CTRL_2:
case MADERA_AIF3_FRAME_CTRL_3:
case MADERA_AIF3_FRAME_CTRL_4:
case MADERA_AIF3_FRAME_CTRL_11:
case MADERA_AIF3_FRAME_CTRL_12:
case MADERA_AIF3_TX_ENABLES:
case MADERA_AIF3_RX_ENABLES:
case MADERA_SPD1_TX_CONTROL:
case MADERA_SPD1_TX_CHANNEL_STATUS_1:
case MADERA_SPD1_TX_CHANNEL_STATUS_2:
case MADERA_SPD1_TX_CHANNEL_STATUS_3:
case MADERA_SLIMBUS_FRAMER_REF_GEAR:
case MADERA_SLIMBUS_RATES_1:
case MADERA_SLIMBUS_RATES_2:
case MADERA_SLIMBUS_RATES_3:
case MADERA_SLIMBUS_RATES_5:
case MADERA_SLIMBUS_RATES_6:
case MADERA_SLIMBUS_RATES_7:
case MADERA_SLIMBUS_RX_CHANNEL_ENABLE:
case MADERA_SLIMBUS_TX_CHANNEL_ENABLE:
case MADERA_SLIMBUS_RX_PORT_STATUS:
case MADERA_SLIMBUS_TX_PORT_STATUS:
case MADERA_PWM1MIX_INPUT_1_SOURCE:
case MADERA_PWM1MIX_INPUT_1_VOLUME:
case MADERA_PWM1MIX_INPUT_2_SOURCE:
case MADERA_PWM1MIX_INPUT_2_VOLUME:
case MADERA_PWM1MIX_INPUT_3_SOURCE:
case MADERA_PWM1MIX_INPUT_3_VOLUME:
case MADERA_PWM1MIX_INPUT_4_SOURCE:
case MADERA_PWM1MIX_INPUT_4_VOLUME:
case MADERA_PWM2MIX_INPUT_1_SOURCE:
case MADERA_PWM2MIX_INPUT_1_VOLUME:
case MADERA_PWM2MIX_INPUT_2_SOURCE:
case MADERA_PWM2MIX_INPUT_2_VOLUME:
case MADERA_PWM2MIX_INPUT_3_SOURCE:
case MADERA_PWM2MIX_INPUT_3_VOLUME:
case MADERA_PWM2MIX_INPUT_4_SOURCE:
case MADERA_PWM2MIX_INPUT_4_VOLUME:
case MADERA_OUT1LMIX_INPUT_1_SOURCE:
case MADERA_OUT1LMIX_INPUT_1_VOLUME:
case MADERA_OUT1LMIX_INPUT_2_SOURCE:
case MADERA_OUT1LMIX_INPUT_2_VOLUME:
case MADERA_OUT1LMIX_INPUT_3_SOURCE:
case MADERA_OUT1LMIX_INPUT_3_VOLUME:
case MADERA_OUT1LMIX_INPUT_4_SOURCE:
case MADERA_OUT1LMIX_INPUT_4_VOLUME:
case MADERA_OUT1RMIX_INPUT_1_SOURCE:
case MADERA_OUT1RMIX_INPUT_1_VOLUME:
case MADERA_OUT1RMIX_INPUT_2_SOURCE:
case MADERA_OUT1RMIX_INPUT_2_VOLUME:
case MADERA_OUT1RMIX_INPUT_3_SOURCE:
case MADERA_OUT1RMIX_INPUT_3_VOLUME:
case MADERA_OUT1RMIX_INPUT_4_SOURCE:
case MADERA_OUT1RMIX_INPUT_4_VOLUME:
case MADERA_OUT4LMIX_INPUT_1_SOURCE:
case MADERA_OUT4LMIX_INPUT_1_VOLUME:
case MADERA_OUT4LMIX_INPUT_2_SOURCE:
case MADERA_OUT4LMIX_INPUT_2_VOLUME:
case MADERA_OUT4LMIX_INPUT_3_SOURCE:
case MADERA_OUT4LMIX_INPUT_3_VOLUME:
case MADERA_OUT4LMIX_INPUT_4_SOURCE:
case MADERA_OUT4LMIX_INPUT_4_VOLUME:
case MADERA_OUT5LMIX_INPUT_1_SOURCE:
case MADERA_OUT5LMIX_INPUT_1_VOLUME:
case MADERA_OUT5LMIX_INPUT_2_SOURCE:
case MADERA_OUT5LMIX_INPUT_2_VOLUME:
case MADERA_OUT5LMIX_INPUT_3_SOURCE:
case MADERA_OUT5LMIX_INPUT_3_VOLUME:
case MADERA_OUT5LMIX_INPUT_4_SOURCE:
case MADERA_OUT5LMIX_INPUT_4_VOLUME:
case MADERA_OUT5RMIX_INPUT_1_SOURCE:
case MADERA_OUT5RMIX_INPUT_1_VOLUME:
case MADERA_OUT5RMIX_INPUT_2_SOURCE:
case MADERA_OUT5RMIX_INPUT_2_VOLUME:
case MADERA_OUT5RMIX_INPUT_3_SOURCE:
case MADERA_OUT5RMIX_INPUT_3_VOLUME:
case MADERA_OUT5RMIX_INPUT_4_SOURCE:
case MADERA_OUT5RMIX_INPUT_4_VOLUME:
case MADERA_AIF1TX1MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX1MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX1MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX1MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX1MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX1MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX1MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX1MIX_INPUT_4_VOLUME:
case MADERA_AIF1TX2MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX2MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX2MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX2MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX2MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX2MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX2MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX2MIX_INPUT_4_VOLUME:
case MADERA_AIF1TX3MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX3MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX3MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX3MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX3MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX3MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX3MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX3MIX_INPUT_4_VOLUME:
case MADERA_AIF1TX4MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX4MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX4MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX4MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX4MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX4MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX4MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX4MIX_INPUT_4_VOLUME:
case MADERA_AIF1TX5MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX5MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX5MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX5MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX5MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX5MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX5MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX5MIX_INPUT_4_VOLUME:
case MADERA_AIF1TX6MIX_INPUT_1_SOURCE:
case MADERA_AIF1TX6MIX_INPUT_1_VOLUME:
case MADERA_AIF1TX6MIX_INPUT_2_SOURCE:
case MADERA_AIF1TX6MIX_INPUT_2_VOLUME:
case MADERA_AIF1TX6MIX_INPUT_3_SOURCE:
case MADERA_AIF1TX6MIX_INPUT_3_VOLUME:
case MADERA_AIF1TX6MIX_INPUT_4_SOURCE:
case MADERA_AIF1TX6MIX_INPUT_4_VOLUME:
case MADERA_AIF2TX1MIX_INPUT_1_SOURCE:
case MADERA_AIF2TX1MIX_INPUT_1_VOLUME:
case MADERA_AIF2TX1MIX_INPUT_2_SOURCE:
case MADERA_AIF2TX1MIX_INPUT_2_VOLUME:
case MADERA_AIF2TX1MIX_INPUT_3_SOURCE:
case MADERA_AIF2TX1MIX_INPUT_3_VOLUME:
case MADERA_AIF2TX1MIX_INPUT_4_SOURCE:
case MADERA_AIF2TX1MIX_INPUT_4_VOLUME:
case MADERA_AIF2TX2MIX_INPUT_1_SOURCE:
case MADERA_AIF2TX2MIX_INPUT_1_VOLUME:
case MADERA_AIF2TX2MIX_INPUT_2_SOURCE:
case MADERA_AIF2TX2MIX_INPUT_2_VOLUME:
case MADERA_AIF2TX2MIX_INPUT_3_SOURCE:
case MADERA_AIF2TX2MIX_INPUT_3_VOLUME:
case MADERA_AIF2TX2MIX_INPUT_4_SOURCE:
case MADERA_AIF2TX2MIX_INPUT_4_VOLUME:
case MADERA_AIF3TX1MIX_INPUT_1_SOURCE:
case MADERA_AIF3TX1MIX_INPUT_1_VOLUME:
case MADERA_AIF3TX1MIX_INPUT_2_SOURCE:
case MADERA_AIF3TX1MIX_INPUT_2_VOLUME:
case MADERA_AIF3TX1MIX_INPUT_3_SOURCE:
case MADERA_AIF3TX1MIX_INPUT_3_VOLUME:
case MADERA_AIF3TX1MIX_INPUT_4_SOURCE:
case MADERA_AIF3TX1MIX_INPUT_4_VOLUME:
case MADERA_AIF3TX2MIX_INPUT_1_SOURCE:
case MADERA_AIF3TX2MIX_INPUT_1_VOLUME:
case MADERA_AIF3TX2MIX_INPUT_2_SOURCE:
case MADERA_AIF3TX2MIX_INPUT_2_VOLUME:
case MADERA_AIF3TX2MIX_INPUT_3_SOURCE:
case MADERA_AIF3TX2MIX_INPUT_3_VOLUME:
case MADERA_AIF3TX2MIX_INPUT_4_SOURCE:
case MADERA_AIF3TX2MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX1MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX1MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX1MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX1MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX1MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX1MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX1MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX1MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX2MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX2MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX2MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX2MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX2MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX2MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX2MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX2MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX3MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX3MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX3MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX3MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX3MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX3MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX3MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX3MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX4MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX4MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX4MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX4MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX4MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX4MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX4MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX4MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX5MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX5MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX5MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX5MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX5MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX5MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX5MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX5MIX_INPUT_4_VOLUME:
case MADERA_SLIMTX6MIX_INPUT_1_SOURCE:
case MADERA_SLIMTX6MIX_INPUT_1_VOLUME:
case MADERA_SLIMTX6MIX_INPUT_2_SOURCE:
case MADERA_SLIMTX6MIX_INPUT_2_VOLUME:
case MADERA_SLIMTX6MIX_INPUT_3_SOURCE:
case MADERA_SLIMTX6MIX_INPUT_3_VOLUME:
case MADERA_SLIMTX6MIX_INPUT_4_SOURCE:
case MADERA_SLIMTX6MIX_INPUT_4_VOLUME:
case MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE:
case MADERA_SPDIF1TX1MIX_INPUT_1_VOLUME:
case MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE:
case MADERA_SPDIF1TX2MIX_INPUT_1_VOLUME:
case MADERA_EQ1MIX_INPUT_1_SOURCE:
case MADERA_EQ1MIX_INPUT_1_VOLUME:
case MADERA_EQ1MIX_INPUT_2_SOURCE:
case MADERA_EQ1MIX_INPUT_2_VOLUME:
case MADERA_EQ1MIX_INPUT_3_SOURCE:
case MADERA_EQ1MIX_INPUT_3_VOLUME:
case MADERA_EQ1MIX_INPUT_4_SOURCE:
case MADERA_EQ1MIX_INPUT_4_VOLUME:
case MADERA_EQ2MIX_INPUT_1_SOURCE:
case MADERA_EQ2MIX_INPUT_1_VOLUME:
case MADERA_EQ2MIX_INPUT_2_SOURCE:
case MADERA_EQ2MIX_INPUT_2_VOLUME:
case MADERA_EQ2MIX_INPUT_3_SOURCE:
case MADERA_EQ2MIX_INPUT_3_VOLUME:
case MADERA_EQ2MIX_INPUT_4_SOURCE:
case MADERA_EQ2MIX_INPUT_4_VOLUME:
case MADERA_EQ3MIX_INPUT_1_SOURCE:
case MADERA_EQ3MIX_INPUT_1_VOLUME:
case MADERA_EQ3MIX_INPUT_2_SOURCE:
case MADERA_EQ3MIX_INPUT_2_VOLUME:
case MADERA_EQ3MIX_INPUT_3_SOURCE:
case MADERA_EQ3MIX_INPUT_3_VOLUME:
case MADERA_EQ3MIX_INPUT_4_SOURCE:
case MADERA_EQ3MIX_INPUT_4_VOLUME:
case MADERA_EQ4MIX_INPUT_1_SOURCE:
case MADERA_EQ4MIX_INPUT_1_VOLUME:
case MADERA_EQ4MIX_INPUT_2_SOURCE:
case MADERA_EQ4MIX_INPUT_2_VOLUME:
case MADERA_EQ4MIX_INPUT_3_SOURCE:
case MADERA_EQ4MIX_INPUT_3_VOLUME:
case MADERA_EQ4MIX_INPUT_4_SOURCE:
case MADERA_EQ4MIX_INPUT_4_VOLUME:
case MADERA_DRC1LMIX_INPUT_1_SOURCE:
case MADERA_DRC1LMIX_INPUT_1_VOLUME:
case MADERA_DRC1LMIX_INPUT_2_SOURCE:
case MADERA_DRC1LMIX_INPUT_2_VOLUME:
case MADERA_DRC1LMIX_INPUT_3_SOURCE:
case MADERA_DRC1LMIX_INPUT_3_VOLUME:
case MADERA_DRC1LMIX_INPUT_4_SOURCE:
case MADERA_DRC1LMIX_INPUT_4_VOLUME:
case MADERA_DRC1RMIX_INPUT_1_SOURCE:
case MADERA_DRC1RMIX_INPUT_1_VOLUME:
case MADERA_DRC1RMIX_INPUT_2_SOURCE:
case MADERA_DRC1RMIX_INPUT_2_VOLUME:
case MADERA_DRC1RMIX_INPUT_3_SOURCE:
case MADERA_DRC1RMIX_INPUT_3_VOLUME:
case MADERA_DRC1RMIX_INPUT_4_SOURCE:
case MADERA_DRC1RMIX_INPUT_4_VOLUME:
case MADERA_DRC2LMIX_INPUT_1_SOURCE:
case MADERA_DRC2LMIX_INPUT_1_VOLUME:
case MADERA_DRC2LMIX_INPUT_2_SOURCE:
case MADERA_DRC2LMIX_INPUT_2_VOLUME:
case MADERA_DRC2LMIX_INPUT_3_SOURCE:
case MADERA_DRC2LMIX_INPUT_3_VOLUME:
case MADERA_DRC2LMIX_INPUT_4_SOURCE:
case MADERA_DRC2LMIX_INPUT_4_VOLUME:
case MADERA_DRC2RMIX_INPUT_1_SOURCE:
case MADERA_DRC2RMIX_INPUT_1_VOLUME:
case MADERA_DRC2RMIX_INPUT_2_SOURCE:
case MADERA_DRC2RMIX_INPUT_2_VOLUME:
case MADERA_DRC2RMIX_INPUT_3_SOURCE:
case MADERA_DRC2RMIX_INPUT_3_VOLUME:
case MADERA_DRC2RMIX_INPUT_4_SOURCE:
case MADERA_DRC2RMIX_INPUT_4_VOLUME:
case MADERA_HPLP1MIX_INPUT_1_SOURCE:
case MADERA_HPLP1MIX_INPUT_1_VOLUME:
case MADERA_HPLP1MIX_INPUT_2_SOURCE:
case MADERA_HPLP1MIX_INPUT_2_VOLUME:
case MADERA_HPLP1MIX_INPUT_3_SOURCE:
case MADERA_HPLP1MIX_INPUT_3_VOLUME:
case MADERA_HPLP1MIX_INPUT_4_SOURCE:
case MADERA_HPLP1MIX_INPUT_4_VOLUME:
case MADERA_HPLP2MIX_INPUT_1_SOURCE:
case MADERA_HPLP2MIX_INPUT_1_VOLUME:
case MADERA_HPLP2MIX_INPUT_2_SOURCE:
case MADERA_HPLP2MIX_INPUT_2_VOLUME:
case MADERA_HPLP2MIX_INPUT_3_SOURCE:
case MADERA_HPLP2MIX_INPUT_3_VOLUME:
case MADERA_HPLP2MIX_INPUT_4_SOURCE:
case MADERA_HPLP2MIX_INPUT_4_VOLUME:
case MADERA_HPLP3MIX_INPUT_1_SOURCE:
case MADERA_HPLP3MIX_INPUT_1_VOLUME:
case MADERA_HPLP3MIX_INPUT_2_SOURCE:
case MADERA_HPLP3MIX_INPUT_2_VOLUME:
case MADERA_HPLP3MIX_INPUT_3_SOURCE:
case MADERA_HPLP3MIX_INPUT_3_VOLUME:
case MADERA_HPLP3MIX_INPUT_4_SOURCE:
case MADERA_HPLP3MIX_INPUT_4_VOLUME:
case MADERA_HPLP4MIX_INPUT_1_SOURCE:
case MADERA_HPLP4MIX_INPUT_1_VOLUME:
case MADERA_HPLP4MIX_INPUT_2_SOURCE:
case MADERA_HPLP4MIX_INPUT_2_VOLUME:
case MADERA_HPLP4MIX_INPUT_3_SOURCE:
case MADERA_HPLP4MIX_INPUT_3_VOLUME:
case MADERA_HPLP4MIX_INPUT_4_SOURCE:
case MADERA_HPLP4MIX_INPUT_4_VOLUME:
case MADERA_DSP1LMIX_INPUT_1_SOURCE:
case MADERA_DSP1LMIX_INPUT_1_VOLUME:
case MADERA_DSP1LMIX_INPUT_2_SOURCE:
case MADERA_DSP1LMIX_INPUT_2_VOLUME:
case MADERA_DSP1LMIX_INPUT_3_SOURCE:
case MADERA_DSP1LMIX_INPUT_3_VOLUME:
case MADERA_DSP1LMIX_INPUT_4_SOURCE:
case MADERA_DSP1LMIX_INPUT_4_VOLUME:
case MADERA_DSP1RMIX_INPUT_1_SOURCE:
case MADERA_DSP1RMIX_INPUT_1_VOLUME:
case MADERA_DSP1RMIX_INPUT_2_SOURCE:
case MADERA_DSP1RMIX_INPUT_2_VOLUME:
case MADERA_DSP1RMIX_INPUT_3_SOURCE:
case MADERA_DSP1RMIX_INPUT_3_VOLUME:
case MADERA_DSP1RMIX_INPUT_4_SOURCE:
case MADERA_DSP1RMIX_INPUT_4_VOLUME:
case MADERA_DSP1AUX1MIX_INPUT_1_SOURCE:
case MADERA_DSP1AUX2MIX_INPUT_1_SOURCE:
case MADERA_DSP1AUX3MIX_INPUT_1_SOURCE:
case MADERA_DSP1AUX4MIX_INPUT_1_SOURCE:
case MADERA_DSP1AUX5MIX_INPUT_1_SOURCE:
case MADERA_DSP1AUX6MIX_INPUT_1_SOURCE:
case MADERA_DSP2LMIX_INPUT_1_SOURCE:
case MADERA_DSP2LMIX_INPUT_1_VOLUME:
case MADERA_DSP2LMIX_INPUT_2_SOURCE:
case MADERA_DSP2LMIX_INPUT_2_VOLUME:
case MADERA_DSP2LMIX_INPUT_3_SOURCE:
case MADERA_DSP2LMIX_INPUT_3_VOLUME:
case MADERA_DSP2LMIX_INPUT_4_SOURCE:
case MADERA_DSP2LMIX_INPUT_4_VOLUME:
case MADERA_DSP2RMIX_INPUT_1_SOURCE:
case MADERA_DSP2RMIX_INPUT_1_VOLUME:
case MADERA_DSP2RMIX_INPUT_2_SOURCE:
case MADERA_DSP2RMIX_INPUT_2_VOLUME:
case MADERA_DSP2RMIX_INPUT_3_SOURCE:
case MADERA_DSP2RMIX_INPUT_3_VOLUME:
case MADERA_DSP2RMIX_INPUT_4_SOURCE:
case MADERA_DSP2RMIX_INPUT_4_VOLUME:
case MADERA_DSP2AUX1MIX_INPUT_1_SOURCE:
case MADERA_DSP2AUX2MIX_INPUT_1_SOURCE:
case MADERA_DSP2AUX3MIX_INPUT_1_SOURCE:
case MADERA_DSP2AUX4MIX_INPUT_1_SOURCE:
case MADERA_DSP2AUX5MIX_INPUT_1_SOURCE:
case MADERA_DSP2AUX6MIX_INPUT_1_SOURCE:
case MADERA_DSP3LMIX_INPUT_1_SOURCE:
case MADERA_DSP3LMIX_INPUT_1_VOLUME:
case MADERA_DSP3LMIX_INPUT_2_SOURCE:
case MADERA_DSP3LMIX_INPUT_2_VOLUME:
case MADERA_DSP3LMIX_INPUT_3_SOURCE:
case MADERA_DSP3LMIX_INPUT_3_VOLUME:
case MADERA_DSP3LMIX_INPUT_4_SOURCE:
case MADERA_DSP3LMIX_INPUT_4_VOLUME:
case MADERA_DSP3RMIX_INPUT_1_SOURCE:
case MADERA_DSP3RMIX_INPUT_1_VOLUME:
case MADERA_DSP3RMIX_INPUT_2_SOURCE:
case MADERA_DSP3RMIX_INPUT_2_VOLUME:
case MADERA_DSP3RMIX_INPUT_3_SOURCE:
case MADERA_DSP3RMIX_INPUT_3_VOLUME:
case MADERA_DSP3RMIX_INPUT_4_SOURCE:
case MADERA_DSP3RMIX_INPUT_4_VOLUME:
case MADERA_DSP3AUX1MIX_INPUT_1_SOURCE:
case MADERA_DSP3AUX2MIX_INPUT_1_SOURCE:
case MADERA_DSP3AUX3MIX_INPUT_1_SOURCE:
case MADERA_DSP3AUX4MIX_INPUT_1_SOURCE:
case MADERA_DSP3AUX5MIX_INPUT_1_SOURCE:
case MADERA_DSP3AUX6MIX_INPUT_1_SOURCE:
case MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE:
case MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE:
case MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE:
case MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE:
case MADERA_ISRC1INT1MIX_INPUT_1_SOURCE:
case MADERA_ISRC1INT2MIX_INPUT_1_SOURCE:
case MADERA_ISRC1INT3MIX_INPUT_1_SOURCE:
case MADERA_ISRC1INT4MIX_INPUT_1_SOURCE:
case MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE:
case MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE:
case MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE:
case MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE:
case MADERA_ISRC2INT1MIX_INPUT_1_SOURCE:
case MADERA_ISRC2INT2MIX_INPUT_1_SOURCE:
case MADERA_ISRC2INT3MIX_INPUT_1_SOURCE:
case MADERA_ISRC2INT4MIX_INPUT_1_SOURCE:
case MADERA_FX_CTRL1:
case MADERA_FX_CTRL2:
case MADERA_EQ1_1 ... MADERA_EQ1_21:
case MADERA_EQ2_1 ... MADERA_EQ2_21:
case MADERA_EQ3_1 ... MADERA_EQ3_21:
case MADERA_EQ4_1 ... MADERA_EQ4_21:
case MADERA_DRC1_CTRL1:
case MADERA_DRC1_CTRL2:
case MADERA_DRC1_CTRL3:
case MADERA_DRC1_CTRL4:
case MADERA_DRC1_CTRL5:
case MADERA_DRC2_CTRL1:
case MADERA_DRC2_CTRL2:
case MADERA_DRC2_CTRL3:
case MADERA_DRC2_CTRL4:
case MADERA_DRC2_CTRL5:
case MADERA_HPLPF1_1:
case MADERA_HPLPF1_2:
case MADERA_HPLPF2_1:
case MADERA_HPLPF2_2:
case MADERA_HPLPF3_1:
case MADERA_HPLPF3_2:
case MADERA_HPLPF4_1:
case MADERA_HPLPF4_2:
case MADERA_ISRC_1_CTRL_1:
case MADERA_ISRC_1_CTRL_2:
case MADERA_ISRC_1_CTRL_3:
case MADERA_ISRC_2_CTRL_1:
case MADERA_ISRC_2_CTRL_2:
case MADERA_ISRC_2_CTRL_3:
case MADERA_DAC_COMP_1:
case MADERA_DAC_COMP_2:
case MADERA_FRF_COEFFICIENT_1L_1:
case MADERA_FRF_COEFFICIENT_1L_2:
case MADERA_FRF_COEFFICIENT_1L_3:
case MADERA_FRF_COEFFICIENT_1L_4:
case MADERA_FRF_COEFFICIENT_1R_1:
case MADERA_FRF_COEFFICIENT_1R_2:
case MADERA_FRF_COEFFICIENT_1R_3:
case MADERA_FRF_COEFFICIENT_1R_4:
case CS47L35_FRF_COEFFICIENT_4L_1:
case CS47L35_FRF_COEFFICIENT_4L_2:
case CS47L35_FRF_COEFFICIENT_4L_3:
case CS47L35_FRF_COEFFICIENT_4L_4:
case CS47L35_FRF_COEFFICIENT_5L_1:
case CS47L35_FRF_COEFFICIENT_5L_2:
case CS47L35_FRF_COEFFICIENT_5L_3:
case CS47L35_FRF_COEFFICIENT_5L_4:
case CS47L35_FRF_COEFFICIENT_5R_1:
case CS47L35_FRF_COEFFICIENT_5R_2:
case CS47L35_FRF_COEFFICIENT_5R_3:
case CS47L35_FRF_COEFFICIENT_5R_4:
case MADERA_GPIO1_CTRL_1 ... MADERA_GPIO16_CTRL_2:
case MADERA_IRQ1_STATUS_1 ... MADERA_IRQ1_STATUS_33:
case MADERA_IRQ1_MASK_1 ... MADERA_IRQ1_MASK_33:
case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
case MADERA_INTERRUPT_DEBOUNCE_7:
case MADERA_IRQ1_CTRL:
return true;
default:
return false;
}
}
static bool cs47l35_16bit_volatile_register(struct device *dev,
unsigned int reg)
{
switch (reg) {
case MADERA_SOFTWARE_RESET:
case MADERA_HARDWARE_REVISION:
case MADERA_WRITE_SEQUENCER_CTRL_0:
case MADERA_WRITE_SEQUENCER_CTRL_1:
case MADERA_WRITE_SEQUENCER_CTRL_2:
case MADERA_HAPTICS_STATUS:
case MADERA_SAMPLE_RATE_1_STATUS:
case MADERA_SAMPLE_RATE_2_STATUS:
case MADERA_SAMPLE_RATE_3_STATUS:
case MADERA_HP_CTRL_1L:
case MADERA_HP_CTRL_1R:
case MADERA_DCS_HP1L_CONTROL:
case MADERA_DCS_HP1R_CONTROL:
case MADERA_MIC_DETECT_1_CONTROL_3:
case MADERA_MIC_DETECT_1_CONTROL_4:
case MADERA_HEADPHONE_DETECT_2:
case MADERA_HEADPHONE_DETECT_3:
case MADERA_HEADPHONE_DETECT_5:
case MADERA_INPUT_ENABLES_STATUS:
case MADERA_OUTPUT_STATUS_1:
case MADERA_RAW_OUTPUT_STATUS_1:
case MADERA_SPD1_TX_CHANNEL_STATUS_1:
case MADERA_SPD1_TX_CHANNEL_STATUS_2:
case MADERA_SPD1_TX_CHANNEL_STATUS_3:
case MADERA_SLIMBUS_RX_PORT_STATUS:
case MADERA_SLIMBUS_TX_PORT_STATUS:
case MADERA_FX_CTRL2:
case MADERA_IRQ1_STATUS_1 ... MADERA_IRQ1_STATUS_33:
case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
return true;
default:
return false;
}
}
static bool cs47l35_32bit_readable_register(struct device *dev,
unsigned int reg)
{
switch (reg) {
case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_252:
case CS47L35_OTP_HPDET_CAL_1 ... CS47L35_OTP_HPDET_CAL_2:
case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_SCRATCH_2:
case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_SCRATCH_2:
case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_SCRATCH_2:
return true;
default:
return cs47l35_is_adsp_memory(reg);
}
}
static bool cs47l35_32bit_volatile_register(struct device *dev,
unsigned int reg)
{
switch (reg) {
case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_252:
case CS47L35_OTP_HPDET_CAL_1 ... CS47L35_OTP_HPDET_CAL_2:
case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_SCRATCH_2:
case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_SCRATCH_2:
case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_SCRATCH_2:
return true;
default:
return cs47l35_is_adsp_memory(reg);
}
}
const struct regmap_config cs47l35_16bit_spi_regmap = {
.name = "cs47l35_16bit",
.reg_bits = 32,
.pad_bits = 16,
.val_bits = 16,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.val_format_endian = REGMAP_ENDIAN_BIG,
.max_register = 0x1b00,
.readable_reg = cs47l35_16bit_readable_register,
.volatile_reg = cs47l35_16bit_volatile_register,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = cs47l35_reg_default,
.num_reg_defaults = ARRAY_SIZE(cs47l35_reg_default),
};
EXPORT_SYMBOL_GPL(cs47l35_16bit_spi_regmap);
const struct regmap_config cs47l35_16bit_i2c_regmap = {
.name = "cs47l35_16bit",
.reg_bits = 32,
.val_bits = 16,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.val_format_endian = REGMAP_ENDIAN_BIG,
.max_register = 0x1b00,
.readable_reg = cs47l35_16bit_readable_register,
.volatile_reg = cs47l35_16bit_volatile_register,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = cs47l35_reg_default,
.num_reg_defaults = ARRAY_SIZE(cs47l35_reg_default),
};
EXPORT_SYMBOL_GPL(cs47l35_16bit_i2c_regmap);
const struct regmap_config cs47l35_32bit_spi_regmap = {
.name = "cs47l35_32bit",
.reg_bits = 32,
.reg_stride = 2,
.pad_bits = 16,
.val_bits = 32,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.val_format_endian = REGMAP_ENDIAN_BIG,
.max_register = MADERA_DSP3_SCRATCH_2,
.readable_reg = cs47l35_32bit_readable_register,
.volatile_reg = cs47l35_32bit_volatile_register,
.cache_type = REGCACHE_RBTREE,
};
EXPORT_SYMBOL_GPL(cs47l35_32bit_spi_regmap);
const struct regmap_config cs47l35_32bit_i2c_regmap = {
.name = "cs47l35_32bit",
.reg_bits = 32,
.reg_stride = 2,
.val_bits = 32,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.val_format_endian = REGMAP_ENDIAN_BIG,
.max_register = MADERA_DSP3_SCRATCH_2,
.readable_reg = cs47l35_32bit_readable_register,
.volatile_reg = cs47l35_32bit_volatile_register,
.cache_type = REGCACHE_RBTREE,
};
EXPORT_SYMBOL_GPL(cs47l35_32bit_i2c_regmap);
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -76,7 +76,7 @@ static struct resource da9063_hwmon_resources[] = {
};
static const struct mfd_cell da9063_devs[] = {
static const struct mfd_cell da9063_common_devs[] = {
{
.name = DA9063_DRVNAME_REGULATORS,
.num_resources = ARRAY_SIZE(da9063_regulators_resources),
......@@ -100,15 +100,19 @@ static const struct mfd_cell da9063_devs[] = {
.resources = da9063_onkey_resources,
.of_compatible = "dlg,da9063-onkey",
},
{
.name = DA9063_DRVNAME_VIBRATION,
},
};
/* Only present on DA9063 , not on DA9063L */
static const struct mfd_cell da9063_devs[] = {
{
.name = DA9063_DRVNAME_RTC,
.num_resources = ARRAY_SIZE(da9063_rtc_resources),
.resources = da9063_rtc_resources,
.of_compatible = "dlg,da9063-rtc",
},
{
.name = DA9063_DRVNAME_VIBRATION,
},
};
static int da9063_clear_fault_log(struct da9063 *da9063)
......@@ -192,7 +196,7 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
dev_err(da9063->dev, "Cannot read chip model id.\n");
return -EIO;
}
if (model != PMIC_DA9063) {
if (model != PMIC_CHIP_ID_DA9063) {
dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model);
return -ENODEV;
}
......@@ -215,7 +219,6 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
return -ENODEV;
}
da9063->model = model;
da9063->variant_code = variant_code;
ret = da9063_irq_init(da9063);
......@@ -226,19 +229,26 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
da9063->irq_base = regmap_irq_chip_get_base(da9063->regmap_irq);
ret = mfd_add_devices(da9063->dev, -1, da9063_devs,
ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base,
NULL);
if (ret)
dev_err(da9063->dev, "Cannot add MFD cells\n");
ret = devm_mfd_add_devices(da9063->dev, PLATFORM_DEVID_NONE,
da9063_common_devs,
ARRAY_SIZE(da9063_common_devs),
NULL, da9063->irq_base, NULL);
if (ret) {
dev_err(da9063->dev, "Failed to add child devices\n");
return ret;
}
return ret;
}
if (da9063->type == PMIC_TYPE_DA9063) {
ret = devm_mfd_add_devices(da9063->dev, PLATFORM_DEVID_NONE,
da9063_devs, ARRAY_SIZE(da9063_devs),
NULL, da9063->irq_base, NULL);
if (ret) {
dev_err(da9063->dev, "Failed to add child devices\n");
return ret;
}
}
void da9063_device_exit(struct da9063 *da9063)
{
mfd_remove_devices(da9063->dev);
da9063_irq_exit(da9063);
return ret;
}
MODULE_DESCRIPTION("PMIC driver for Dialog DA9063");
......
......@@ -29,78 +29,33 @@
#include <linux/regulator/of_regulator.h>
static const struct regmap_range da9063_ad_readable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_AD_REG_SECOND_D,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
}, {
.range_min = DA9063_REG_SEQ_A,
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_T_OFFSET,
.range_max = DA9063_AD_REG_GP_ID_19,
}, {
.range_min = DA9063_REG_CHIP_ID,
.range_max = DA9063_REG_CHIP_VARIANT,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_AD_REG_SECOND_D),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_AD_REG_GP_ID_19),
regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
};
static const struct regmap_range da9063_ad_writeable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_PAGE_CON,
}, {
.range_min = DA9063_REG_FAULT_LOG,
.range_max = DA9063_REG_VSYS_MON,
}, {
.range_min = DA9063_REG_COUNT_S,
.range_max = DA9063_AD_REG_ALARM_Y,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
}, {
.range_min = DA9063_REG_SEQ_A,
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_CONFIG_I,
.range_max = DA9063_AD_REG_MON_REG_4,
}, {
.range_min = DA9063_AD_REG_GP_ID_0,
.range_max = DA9063_AD_REG_GP_ID_19,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON),
regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON),
regmap_reg_range(DA9063_REG_COUNT_S, DA9063_AD_REG_ALARM_Y),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_AD_REG_MON_REG_4),
regmap_reg_range(DA9063_AD_REG_GP_ID_0, DA9063_AD_REG_GP_ID_19),
};
static const struct regmap_range da9063_ad_volatile_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_EVENT_D,
}, {
.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_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,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D),
regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B),
regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F),
regmap_reg_range(DA9063_REG_BCORE2_CONT, DA9063_REG_LDO11_CONT),
regmap_reg_range(DA9063_REG_DVC_1, DA9063_REG_ADC_MAN),
regmap_reg_range(DA9063_REG_ADC_RES_L, DA9063_AD_REG_SECOND_D),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_SEQ),
regmap_reg_range(DA9063_REG_EN_32K, DA9063_REG_EN_32K),
regmap_reg_range(DA9063_AD_REG_MON_REG_5, DA9063_AD_REG_MON_REG_6),
};
static const struct regmap_access_table da9063_ad_readable_table = {
......@@ -119,78 +74,33 @@ static const struct regmap_access_table da9063_ad_volatile_table = {
};
static const struct regmap_range da9063_bb_readable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_BB_REG_SECOND_D,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
}, {
.range_min = DA9063_REG_SEQ_A,
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_T_OFFSET,
.range_max = DA9063_BB_REG_GP_ID_19,
}, {
.range_min = DA9063_REG_CHIP_ID,
.range_max = DA9063_REG_CHIP_VARIANT,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_BB_REG_SECOND_D),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19),
regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
};
static const struct regmap_range da9063_bb_writeable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_PAGE_CON,
}, {
.range_min = DA9063_REG_FAULT_LOG,
.range_max = DA9063_REG_VSYS_MON,
}, {
.range_min = DA9063_REG_COUNT_S,
.range_max = DA9063_BB_REG_ALARM_Y,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
}, {
.range_min = DA9063_REG_SEQ_A,
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_CONFIG_I,
.range_max = DA9063_BB_REG_MON_REG_4,
}, {
.range_min = DA9063_BB_REG_GP_ID_0,
.range_max = DA9063_BB_REG_GP_ID_19,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON),
regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON),
regmap_reg_range(DA9063_REG_COUNT_S, DA9063_BB_REG_ALARM_Y),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4),
regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19),
};
static const struct regmap_range da9063_bb_volatile_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_EVENT_D,
}, {
.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_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,
},
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D),
regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B),
regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F),
regmap_reg_range(DA9063_REG_BCORE2_CONT, DA9063_REG_LDO11_CONT),
regmap_reg_range(DA9063_REG_DVC_1, DA9063_REG_ADC_MAN),
regmap_reg_range(DA9063_REG_ADC_RES_L, DA9063_BB_REG_SECOND_D),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_SEQ),
regmap_reg_range(DA9063_REG_EN_32K, DA9063_REG_EN_32K),
regmap_reg_range(DA9063_BB_REG_MON_REG_5, DA9063_BB_REG_MON_REG_6),
};
static const struct regmap_access_table da9063_bb_readable_table = {
......@@ -208,6 +118,50 @@ static const struct regmap_access_table da9063_bb_volatile_table = {
.n_yes_ranges = ARRAY_SIZE(da9063_bb_volatile_ranges),
};
static const struct regmap_range da9063l_bb_readable_ranges[] = {
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_MON_A10_RES),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19),
regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
};
static const struct regmap_range da9063l_bb_writeable_ranges[] = {
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON),
regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4),
regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19),
};
static const struct regmap_range da9063l_bb_volatile_ranges[] = {
regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D),
regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B),
regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F),
regmap_reg_range(DA9063_REG_BCORE2_CONT, DA9063_REG_LDO11_CONT),
regmap_reg_range(DA9063_REG_DVC_1, DA9063_REG_ADC_MAN),
regmap_reg_range(DA9063_REG_ADC_RES_L, DA9063_REG_MON_A10_RES),
regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_SEQ),
regmap_reg_range(DA9063_REG_EN_32K, DA9063_REG_EN_32K),
regmap_reg_range(DA9063_BB_REG_MON_REG_5, DA9063_BB_REG_MON_REG_6),
};
static const struct regmap_access_table da9063l_bb_readable_table = {
.yes_ranges = da9063l_bb_readable_ranges,
.n_yes_ranges = ARRAY_SIZE(da9063l_bb_readable_ranges),
};
static const struct regmap_access_table da9063l_bb_writeable_table = {
.yes_ranges = da9063l_bb_writeable_ranges,
.n_yes_ranges = ARRAY_SIZE(da9063l_bb_writeable_ranges),
};
static const struct regmap_access_table da9063l_bb_volatile_table = {
.yes_ranges = da9063l_bb_volatile_ranges,
.n_yes_ranges = ARRAY_SIZE(da9063l_bb_volatile_ranges),
};
static const struct regmap_range_cfg da9063_range_cfg[] = {
{
.range_min = DA9063_REG_PAGE_CON,
......@@ -232,11 +186,12 @@ static struct regmap_config da9063_regmap_config = {
static const struct of_device_id da9063_dt_ids[] = {
{ .compatible = "dlg,da9063", },
{ .compatible = "dlg,da9063l", },
{ }
};
MODULE_DEVICE_TABLE(of, da9063_dt_ids);
static int da9063_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
const struct i2c_device_id *id)
{
struct da9063 *da9063;
int ret;
......@@ -248,11 +203,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, da9063);
da9063->dev = &i2c->dev;
da9063->chip_irq = i2c->irq;
da9063->type = id->driver_data;
if (da9063->variant_code == PMIC_DA9063_AD) {
da9063_regmap_config.rd_table = &da9063_ad_readable_table;
da9063_regmap_config.wr_table = &da9063_ad_writeable_table;
da9063_regmap_config.volatile_table = &da9063_ad_volatile_table;
} else if (da9063->type == PMIC_TYPE_DA9063L) {
da9063_regmap_config.rd_table = &da9063l_bb_readable_table;
da9063_regmap_config.wr_table = &da9063l_bb_writeable_table;
da9063_regmap_config.volatile_table = &da9063l_bb_volatile_table;
} else {
da9063_regmap_config.rd_table = &da9063_bb_readable_table;
da9063_regmap_config.wr_table = &da9063_bb_writeable_table;
......@@ -270,17 +230,9 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
return da9063_device_init(da9063, i2c->irq);
}
static int da9063_i2c_remove(struct i2c_client *i2c)
{
struct da9063 *da9063 = i2c_get_clientdata(i2c);
da9063_device_exit(da9063);
return 0;
}
static const struct i2c_device_id da9063_i2c_id[] = {
{"da9063", PMIC_DA9063},
{ "da9063", PMIC_TYPE_DA9063 },
{ "da9063l", PMIC_TYPE_DA9063L },
{},
};
MODULE_DEVICE_TABLE(i2c, da9063_i2c_id);
......@@ -291,7 +243,6 @@ static struct i2c_driver da9063_i2c_driver = {
.of_match_table = of_match_ptr(da9063_dt_ids),
},
.probe = da9063_i2c_probe,
.remove = da9063_i2c_remove,
.id_table = da9063_i2c_id,
};
......
......@@ -28,132 +28,145 @@
static const struct regmap_irq da9063_irqs[] = {
/* DA9063 event A register */
[DA9063_IRQ_ONKEY] = {
.reg_offset = DA9063_REG_EVENT_A_OFFSET,
.mask = DA9063_M_ONKEY,
},
[DA9063_IRQ_ALARM] = {
.reg_offset = DA9063_REG_EVENT_A_OFFSET,
.mask = DA9063_M_ALARM,
},
[DA9063_IRQ_TICK] = {
.reg_offset = DA9063_REG_EVENT_A_OFFSET,
.mask = DA9063_M_TICK,
},
[DA9063_IRQ_ADC_RDY] = {
.reg_offset = DA9063_REG_EVENT_A_OFFSET,
.mask = DA9063_M_ADC_RDY,
},
[DA9063_IRQ_SEQ_RDY] = {
.reg_offset = DA9063_REG_EVENT_A_OFFSET,
.mask = DA9063_M_SEQ_RDY,
},
REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),
REGMAP_IRQ_REG(DA9063_IRQ_ALARM,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_ALARM),
REGMAP_IRQ_REG(DA9063_IRQ_TICK,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_TICK),
REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),
REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),
/* DA9063 event B register */
[DA9063_IRQ_WAKE] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_WAKE,
},
[DA9063_IRQ_TEMP] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_TEMP,
},
[DA9063_IRQ_COMP_1V2] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_COMP_1V2,
},
[DA9063_IRQ_LDO_LIM] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_LDO_LIM,
},
[DA9063_IRQ_REG_UVOV] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_UVOV,
},
[DA9063_IRQ_DVC_RDY] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_DVC_RDY,
},
[DA9063_IRQ_VDD_MON] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_VDD_MON,
},
[DA9063_IRQ_WARN] = {
.reg_offset = DA9063_REG_EVENT_B_OFFSET,
.mask = DA9063_M_VDD_WARN,
},
REGMAP_IRQ_REG(DA9063_IRQ_WAKE,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),
REGMAP_IRQ_REG(DA9063_IRQ_TEMP,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),
REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),
REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),
REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),
REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),
REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),
REGMAP_IRQ_REG(DA9063_IRQ_WARN,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),
/* DA9063 event C register */
[DA9063_IRQ_GPI0] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI0,
},
[DA9063_IRQ_GPI1] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI1,
},
[DA9063_IRQ_GPI2] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI2,
},
[DA9063_IRQ_GPI3] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI3,
},
[DA9063_IRQ_GPI4] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI4,
},
[DA9063_IRQ_GPI5] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI5,
},
[DA9063_IRQ_GPI6] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI6,
},
[DA9063_IRQ_GPI7] = {
.reg_offset = DA9063_REG_EVENT_C_OFFSET,
.mask = DA9063_M_GPI7,
},
REGMAP_IRQ_REG(DA9063_IRQ_GPI0,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),
REGMAP_IRQ_REG(DA9063_IRQ_GPI1,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),
REGMAP_IRQ_REG(DA9063_IRQ_GPI2,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),
REGMAP_IRQ_REG(DA9063_IRQ_GPI3,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),
REGMAP_IRQ_REG(DA9063_IRQ_GPI4,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),
REGMAP_IRQ_REG(DA9063_IRQ_GPI5,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),
REGMAP_IRQ_REG(DA9063_IRQ_GPI6,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),
REGMAP_IRQ_REG(DA9063_IRQ_GPI7,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),
/* DA9063 event D register */
[DA9063_IRQ_GPI8] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI8,
},
[DA9063_IRQ_GPI9] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI9,
},
[DA9063_IRQ_GPI10] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI10,
},
[DA9063_IRQ_GPI11] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI11,
},
[DA9063_IRQ_GPI12] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI12,
},
[DA9063_IRQ_GPI13] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI13,
},
[DA9063_IRQ_GPI14] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI14,
},
[DA9063_IRQ_GPI15] = {
.reg_offset = DA9063_REG_EVENT_D_OFFSET,
.mask = DA9063_M_GPI15,
},
REGMAP_IRQ_REG(DA9063_IRQ_GPI8,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),
REGMAP_IRQ_REG(DA9063_IRQ_GPI9,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),
REGMAP_IRQ_REG(DA9063_IRQ_GPI10,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),
REGMAP_IRQ_REG(DA9063_IRQ_GPI11,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),
REGMAP_IRQ_REG(DA9063_IRQ_GPI12,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),
REGMAP_IRQ_REG(DA9063_IRQ_GPI13,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),
REGMAP_IRQ_REG(DA9063_IRQ_GPI14,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),
REGMAP_IRQ_REG(DA9063_IRQ_GPI15,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),
};
static const struct regmap_irq_chip da9063_irq_chip = {
.name = "da9063-irq",
.irqs = da9063_irqs,
.num_irqs = DA9063_NUM_IRQ,
.num_irqs = ARRAY_SIZE(da9063_irqs),
.num_regs = 4,
.status_base = DA9063_REG_EVENT_A,
.mask_base = DA9063_REG_IRQ_MASK_A,
.ack_base = DA9063_REG_EVENT_A,
.init_ack_masked = true,
};
static const struct regmap_irq da9063l_irqs[] = {
/* DA9063 event A register */
REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),
REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),
REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,
DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),
/* DA9063 event B register */
REGMAP_IRQ_REG(DA9063_IRQ_WAKE,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),
REGMAP_IRQ_REG(DA9063_IRQ_TEMP,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),
REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),
REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),
REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),
REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),
REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),
REGMAP_IRQ_REG(DA9063_IRQ_WARN,
DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),
/* DA9063 event C register */
REGMAP_IRQ_REG(DA9063_IRQ_GPI0,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),
REGMAP_IRQ_REG(DA9063_IRQ_GPI1,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),
REGMAP_IRQ_REG(DA9063_IRQ_GPI2,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),
REGMAP_IRQ_REG(DA9063_IRQ_GPI3,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),
REGMAP_IRQ_REG(DA9063_IRQ_GPI4,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),
REGMAP_IRQ_REG(DA9063_IRQ_GPI5,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),
REGMAP_IRQ_REG(DA9063_IRQ_GPI6,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),
REGMAP_IRQ_REG(DA9063_IRQ_GPI7,
DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),
/* DA9063 event D register */
REGMAP_IRQ_REG(DA9063_IRQ_GPI8,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),
REGMAP_IRQ_REG(DA9063_IRQ_GPI9,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),
REGMAP_IRQ_REG(DA9063_IRQ_GPI10,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),
REGMAP_IRQ_REG(DA9063_IRQ_GPI11,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),
REGMAP_IRQ_REG(DA9063_IRQ_GPI12,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),
REGMAP_IRQ_REG(DA9063_IRQ_GPI13,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),
REGMAP_IRQ_REG(DA9063_IRQ_GPI14,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),
REGMAP_IRQ_REG(DA9063_IRQ_GPI15,
DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),
};
static const struct regmap_irq_chip da9063l_irq_chip = {
.name = "da9063l-irq",
.irqs = da9063l_irqs,
.num_irqs = ARRAY_SIZE(da9063l_irqs),
.num_regs = 4,
.status_base = DA9063_REG_EVENT_A,
.mask_base = DA9063_REG_IRQ_MASK_A,
......@@ -163,6 +176,7 @@ static const struct regmap_irq_chip da9063_irq_chip = {
int da9063_irq_init(struct da9063 *da9063)
{
const struct regmap_irq_chip *irq_chip;
int ret;
if (!da9063->chip_irq) {
......@@ -170,10 +184,15 @@ int da9063_irq_init(struct da9063 *da9063)
return -EINVAL;
}
ret = regmap_add_irq_chip(da9063->regmap, da9063->chip_irq,
if (da9063->type == PMIC_TYPE_DA9063)
irq_chip = &da9063_irq_chip;
else
irq_chip = &da9063l_irq_chip;
ret = devm_regmap_add_irq_chip(da9063->dev, da9063->regmap,
da9063->chip_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
da9063->irq_base, &da9063_irq_chip,
&da9063->regmap_irq);
da9063->irq_base, irq_chip, &da9063->regmap_irq);
if (ret) {
dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n",
da9063->chip_irq, ret);
......@@ -182,8 +201,3 @@ int da9063_irq_init(struct da9063 *da9063)
return 0;
}
void da9063_irq_exit(struct da9063 *da9063)
{
regmap_del_irq_chip(da9063->chip_irq, da9063->regmap_irq);
}
......@@ -194,6 +194,7 @@ static bool dln2_transfer_complete(struct dln2_dev *dln2, struct urb *urb,
struct device *dev = &dln2->interface->dev;
struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
struct dln2_rx_context *rxc;
unsigned long flags;
bool valid_slot = false;
if (rx_slot >= DLN2_MAX_RX_SLOTS)
......@@ -201,18 +202,13 @@ static bool dln2_transfer_complete(struct dln2_dev *dln2, struct urb *urb,
rxc = &rxs->slots[rx_slot];
/*
* No need to disable interrupts as this lock is not taken in interrupt
* context elsewhere in this driver. This function (or its callers) are
* also not exported to other modules.
*/
spin_lock(&rxs->lock);
spin_lock_irqsave(&rxs->lock, flags);
if (rxc->in_use && !rxc->urb) {
rxc->urb = urb;
complete(&rxc->done);
valid_slot = true;
}
spin_unlock(&rxs->lock);
spin_unlock_irqrestore(&rxs->lock, flags);
out:
if (!valid_slot)
......
......@@ -49,7 +49,7 @@ static struct regmap_config hi655x_regmap_config = {
.reg_bits = 32,
.reg_stride = HI655X_STRIDE,
.val_bits = 8,
.max_register = HI655X_BUS_ADDR(0xFFF),
.max_register = HI655X_BUS_ADDR(0x400) - HI655X_STRIDE,
};
static struct resource pwrkey_resources[] = {
......
......@@ -178,6 +178,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x31c2), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x31c4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x31c6), (kernel_ulong_t)&bxt_info },
/* ICL-LP */
{ PCI_VDEVICE(INTEL, 0x34a8), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x34a9), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x34aa), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0x34ab), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0x34c5), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34c6), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34c7), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x34e8), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34e9), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&spt_info },
/* APL */
{ PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info },
......
......@@ -143,7 +143,7 @@ static struct platform_device *kempld_pdev;
static int kempld_create_platform_device(const struct dmi_system_id *id)
{
struct kempld_platform_data *pdata = id->driver_data;
const struct kempld_platform_data *pdata = id->driver_data;
int ret;
kempld_pdev = platform_device_alloc("kempld", -1);
......@@ -259,7 +259,7 @@ EXPORT_SYMBOL_GPL(kempld_write32);
*/
void kempld_get_mutex(struct kempld_device_data *pld)
{
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
mutex_lock(&pld->lock);
pdata->get_hardware_mutex(pld);
......@@ -272,7 +272,7 @@ EXPORT_SYMBOL_GPL(kempld_get_mutex);
*/
void kempld_release_mutex(struct kempld_device_data *pld)
{
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
pdata->release_hardware_mutex(pld);
mutex_unlock(&pld->lock);
......@@ -290,7 +290,7 @@ EXPORT_SYMBOL_GPL(kempld_release_mutex);
static int kempld_get_info(struct kempld_device_data *pld)
{
int ret;
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
char major, minor;
ret = pdata->get_info(pld);
......@@ -332,7 +332,7 @@ static int kempld_get_info(struct kempld_device_data *pld)
*/
static int kempld_register_cells(struct kempld_device_data *pld)
{
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
return pdata->register_cells(pld);
}
......@@ -444,7 +444,8 @@ static int kempld_detect_device(struct kempld_device_data *pld)
static int kempld_probe(struct platform_device *pdev)
{
struct kempld_platform_data *pdata = dev_get_platdata(&pdev->dev);
const struct kempld_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct kempld_device_data *pld;
struct resource *ioport;
......@@ -476,7 +477,7 @@ static int kempld_probe(struct platform_device *pdev)
static int kempld_remove(struct platform_device *pdev)
{
struct kempld_device_data *pld = platform_get_drvdata(pdev);
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
sysfs_remove_group(&pld->dev->kobj, &pld_attr_group);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Core MFD support for Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/madera/core.h>
#include <linux/mfd/madera/registers.h>
#include "madera.h"
#define CS47L35_SILICON_ID 0x6360
#define CS47L85_SILICON_ID 0x6338
#define CS47L90_SILICON_ID 0x6364
#define MADERA_32KZ_MCLK2 1
static const char * const madera_core_supplies[] = {
"AVDD",
"DBVDD1",
};
static const struct mfd_cell madera_ldo1_devs[] = {
{ .name = "madera-ldo1" },
};
static const char * const cs47l35_supplies[] = {
"MICVDD",
"DBVDD2",
"CPVDD1",
"CPVDD2",
"SPKVDD",
};
static const struct mfd_cell cs47l35_devs[] = {
{ .name = "madera-pinctrl", },
{ .name = "madera-irq", },
{ .name = "madera-micsupp", },
{ .name = "madera-gpio", },
{ .name = "madera-extcon", },
{
.name = "cs47l35-codec",
.parent_supplies = cs47l35_supplies,
.num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
},
};
static const char * const cs47l85_supplies[] = {
"MICVDD",
"DBVDD2",
"DBVDD3",
"DBVDD4",
"CPVDD1",
"CPVDD2",
"SPKVDDL",
"SPKVDDR",
};
static const struct mfd_cell cs47l85_devs[] = {
{ .name = "madera-pinctrl", },
{ .name = "madera-irq", },
{ .name = "madera-micsupp" },
{ .name = "madera-gpio", },
{ .name = "madera-extcon", },
{
.name = "cs47l85-codec",
.parent_supplies = cs47l85_supplies,
.num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
},
};
static const char * const cs47l90_supplies[] = {
"MICVDD",
"DBVDD2",
"DBVDD3",
"DBVDD4",
"CPVDD1",
"CPVDD2",
};
static const struct mfd_cell cs47l90_devs[] = {
{ .name = "madera-pinctrl", },
{ .name = "madera-irq", },
{ .name = "madera-micsupp", },
{ .name = "madera-gpio", },
{ .name = "madera-extcon", },
{
.name = "cs47l90-codec",
.parent_supplies = cs47l90_supplies,
.num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
},
};
/* Used by madera-i2c and madera-spi drivers */
const char *madera_name_from_type(enum madera_type type)
{
switch (type) {
case CS47L35:
return "CS47L35";
case CS47L85:
return "CS47L85";
case CS47L90:
return "CS47L90";
case CS47L91:
return "CS47L91";
case WM1840:
return "WM1840";
default:
return "Unknown";
}
}
EXPORT_SYMBOL_GPL(madera_name_from_type);
#define MADERA_BOOT_POLL_MAX_INTERVAL_US 5000
#define MADERA_BOOT_POLL_TIMEOUT_US 25000
static int madera_wait_for_boot(struct madera *madera)
{
unsigned int val;
int ret;
/*
* We can't use an interrupt as we need to runtime resume to do so,
* so we poll the status bit. This won't race with the interrupt
* handler because it will be blocked on runtime resume.
*/
ret = regmap_read_poll_timeout(madera->regmap,
MADERA_IRQ1_RAW_STATUS_1,
val,
(val & MADERA_BOOT_DONE_STS1),
MADERA_BOOT_POLL_MAX_INTERVAL_US,
MADERA_BOOT_POLL_TIMEOUT_US);
if (ret)
dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
/*
* BOOT_DONE defaults to unmasked on boot so we must ack it.
* Do this unconditionally to avoid interrupt storms.
*/
regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
MADERA_BOOT_DONE_EINT1);
pm_runtime_mark_last_busy(madera->dev);
return ret;
}
static int madera_soft_reset(struct madera *madera)
{
int ret;
ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
if (ret != 0) {
dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
return ret;
}
/* Allow time for internal clocks to startup after reset */
usleep_range(1000, 2000);
return 0;
}
static void madera_enable_hard_reset(struct madera *madera)
{
if (!madera->pdata.reset)
return;
/*
* There are many existing out-of-tree users of these codecs that we
* can't break so preserve the expected behaviour of setting the line
* low to assert reset.
*/
gpiod_set_raw_value_cansleep(madera->pdata.reset, 0);
}
static void madera_disable_hard_reset(struct madera *madera)
{
if (!madera->pdata.reset)
return;
gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
usleep_range(1000, 2000);
}
static int __maybe_unused madera_runtime_resume(struct device *dev)
{
struct madera *madera = dev_get_drvdata(dev);
int ret;
dev_dbg(dev, "Leaving sleep mode\n");
ret = regulator_enable(madera->dcvdd);
if (ret) {
dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
return ret;
}
regcache_cache_only(madera->regmap, false);
regcache_cache_only(madera->regmap_32bit, false);
ret = madera_wait_for_boot(madera);
if (ret)
goto err;
ret = regcache_sync(madera->regmap);
if (ret) {
dev_err(dev, "Failed to restore 16-bit register cache\n");
goto err;
}
ret = regcache_sync(madera->regmap_32bit);
if (ret) {
dev_err(dev, "Failed to restore 32-bit register cache\n");
goto err;
}
return 0;
err:
regcache_cache_only(madera->regmap_32bit, true);
regcache_cache_only(madera->regmap, true);
regulator_disable(madera->dcvdd);
return ret;
}
static int __maybe_unused madera_runtime_suspend(struct device *dev)
{
struct madera *madera = dev_get_drvdata(dev);
dev_dbg(madera->dev, "Entering sleep mode\n");
regcache_cache_only(madera->regmap, true);
regcache_mark_dirty(madera->regmap);
regcache_cache_only(madera->regmap_32bit, true);
regcache_mark_dirty(madera->regmap_32bit);
regulator_disable(madera->dcvdd);
return 0;
}
const struct dev_pm_ops madera_pm_ops = {
SET_RUNTIME_PM_OPS(madera_runtime_suspend,
madera_runtime_resume,
NULL)
};
EXPORT_SYMBOL_GPL(madera_pm_ops);
const struct of_device_id madera_of_match[] = {
{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
{ .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
{ .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
{}
};
EXPORT_SYMBOL_GPL(madera_of_match);
static int madera_get_reset_gpio(struct madera *madera)
{
struct gpio_desc *reset;
int ret;
if (madera->pdata.reset)
return 0;
reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(reset)) {
ret = PTR_ERR(reset);
if (ret != -EPROBE_DEFER)
dev_err(madera->dev, "Failed to request /RESET: %d\n",
ret);
return ret;
}
/*
* A hard reset is needed for full reset of the chip. We allow running
* without hard reset only because it can be useful for early
* prototyping and some debugging, but we need to warn it's not ideal.
*/
if (!reset)
dev_warn(madera->dev,
"Running without reset GPIO is not recommended\n");
madera->pdata.reset = reset;
return 0;
}
static void madera_set_micbias_info(struct madera *madera)
{
/*
* num_childbias is an array because future codecs can have different
* childbiases for each micbias. Unspecified values default to 0.
*/
switch (madera->type) {
case CS47L35:
madera->num_micbias = 2;
madera->num_childbias[0] = 2;
madera->num_childbias[1] = 2;
return;
case CS47L85:
case WM1840:
madera->num_micbias = 4;
/* no child biases */
return;
case CS47L90:
case CS47L91:
madera->num_micbias = 2;
madera->num_childbias[0] = 4;
madera->num_childbias[1] = 4;
return;
default:
return;
}
}
int madera_dev_init(struct madera *madera)
{
struct device *dev = madera->dev;
unsigned int hwid;
int (*patch_fn)(struct madera *) = NULL;
const struct mfd_cell *mfd_devs;
int n_devs = 0;
int i, ret;
dev_set_drvdata(madera->dev, madera);
BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
madera_set_micbias_info(madera);
/*
* We need writable hw config info that all children can share.
* Simplest to take one shared copy of pdata struct.
*/
if (dev_get_platdata(madera->dev)) {
memcpy(&madera->pdata, dev_get_platdata(madera->dev),
sizeof(madera->pdata));
}
ret = madera_get_reset_gpio(madera);
if (ret)
return ret;
regcache_cache_only(madera->regmap, true);
regcache_cache_only(madera->regmap_32bit, true);
for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
madera->core_supplies[i].supply = madera_core_supplies[i];
madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
/*
* On some codecs DCVDD could be supplied by the internal LDO1.
* For those we must add the LDO1 driver before requesting DCVDD
* No devm_ because we need to control shutdown order of children.
*/
switch (madera->type) {
case CS47L35:
case CS47L90:
case CS47L91:
break;
case CS47L85:
case WM1840:
ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
madera_ldo1_devs,
ARRAY_SIZE(madera_ldo1_devs),
NULL, 0, NULL);
if (ret) {
dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
return ret;
}
break;
default:
/* No point continuing if the type is unknown */
dev_err(madera->dev, "Unknown device type %d\n", madera->type);
return -ENODEV;
}
ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
madera->core_supplies);
if (ret) {
dev_err(dev, "Failed to request core supplies: %d\n", ret);
goto err_devs;
}
/*
* Don't use devres here. If the regulator is one of our children it
* will already have been removed before devres cleanup on this mfd
* driver tries to call put() on it. We need control of shutdown order.
*/
madera->dcvdd = regulator_get(madera->dev, "DCVDD");
if (IS_ERR(madera->dcvdd)) {
ret = PTR_ERR(madera->dcvdd);
dev_err(dev, "Failed to request DCVDD: %d\n", ret);
goto err_devs;
}
ret = regulator_bulk_enable(madera->num_core_supplies,
madera->core_supplies);
if (ret) {
dev_err(dev, "Failed to enable core supplies: %d\n", ret);
goto err_dcvdd;
}
ret = regulator_enable(madera->dcvdd);
if (ret) {
dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
goto err_enable;
}
madera_disable_hard_reset(madera);
regcache_cache_only(madera->regmap, false);
regcache_cache_only(madera->regmap_32bit, false);
/*
* Now we can power up and verify that this is a chip we know about
* before we start doing any writes to its registers.
*/
ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
if (ret) {
dev_err(dev, "Failed to read ID register: %d\n", ret);
goto err_reset;
}
switch (hwid) {
case CS47L35_SILICON_ID:
if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
switch (madera->type) {
case CS47L35:
patch_fn = cs47l35_patch;
mfd_devs = cs47l35_devs;
n_devs = ARRAY_SIZE(cs47l35_devs);
break;
default:
break;
}
}
break;
case CS47L85_SILICON_ID:
if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
switch (madera->type) {
case CS47L85:
case WM1840:
patch_fn = cs47l85_patch;
mfd_devs = cs47l85_devs;
n_devs = ARRAY_SIZE(cs47l85_devs);
break;
default:
break;
}
}
break;
case CS47L90_SILICON_ID:
if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
switch (madera->type) {
case CS47L90:
case CS47L91:
patch_fn = cs47l90_patch;
mfd_devs = cs47l90_devs;
n_devs = ARRAY_SIZE(cs47l90_devs);
break;
default:
break;
}
}
break;
default:
dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
ret = -EINVAL;
goto err_reset;
}
if (!n_devs) {
dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
madera->type_name);
ret = -ENODEV;
goto err_reset;
}
/*
* It looks like a device we support. If we don't have a hard reset
* we can now attempt a soft reset.
*/
if (!madera->pdata.reset) {
ret = madera_soft_reset(madera);
if (ret)
goto err_reset;
}
ret = madera_wait_for_boot(madera);
if (ret) {
dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
goto err_reset;
}
ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
&madera->rev);
if (ret) {
dev_err(dev, "Failed to read revision register: %d\n", ret);
goto err_reset;
}
madera->rev &= MADERA_HW_REVISION_MASK;
dev_info(dev, "%s silicon revision %d\n", madera->type_name,
madera->rev);
/* Apply hardware patch */
if (patch_fn) {
ret = patch_fn(madera);
if (ret) {
dev_err(madera->dev, "Failed to apply patch %d\n", ret);
goto err_reset;
}
}
/* Init 32k clock sourced from MCLK2 */
ret = regmap_update_bits(madera->regmap,
MADERA_CLOCK_32K_1,
MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
if (ret) {
dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
goto err_reset;
}
pm_runtime_set_active(madera->dev);
pm_runtime_enable(madera->dev);
pm_runtime_set_autosuspend_delay(madera->dev, 100);
pm_runtime_use_autosuspend(madera->dev);
/* No devm_ because we need to control shutdown order of children */
ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
mfd_devs, n_devs,
NULL, 0, NULL);
if (ret) {
dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
goto err_pm_runtime;
}
return 0;
err_pm_runtime:
pm_runtime_disable(madera->dev);
err_reset:
madera_enable_hard_reset(madera);
regulator_disable(madera->dcvdd);
err_enable:
regulator_bulk_disable(madera->num_core_supplies,
madera->core_supplies);
err_dcvdd:
regulator_put(madera->dcvdd);
err_devs:
mfd_remove_devices(dev);
return ret;
}
EXPORT_SYMBOL_GPL(madera_dev_init);
int madera_dev_exit(struct madera *madera)
{
/* Prevent any IRQs being serviced while we clean up */
disable_irq(madera->irq);
/*
* DCVDD could be supplied by a child node, we must disable it before
* removing the children, and prevent PM runtime from turning it back on
*/
pm_runtime_disable(madera->dev);
regulator_disable(madera->dcvdd);
regulator_put(madera->dcvdd);
mfd_remove_devices(madera->dev);
madera_enable_hard_reset(madera);
regulator_bulk_disable(madera->num_core_supplies,
madera->core_supplies);
return 0;
}
EXPORT_SYMBOL_GPL(madera_dev_exit);
MODULE_DESCRIPTION("Madera core MFD driver");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* I2C bus interface to Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/mfd/madera/core.h>
#include "madera.h"
static int madera_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct madera *madera;
const struct regmap_config *regmap_16bit_config = NULL;
const struct regmap_config *regmap_32bit_config = NULL;
const void *of_data;
unsigned long type;
const char *name;
int ret;
of_data = of_device_get_match_data(&i2c->dev);
if (of_data)
type = (unsigned long)of_data;
else
type = id->driver_data;
switch (type) {
case CS47L35:
if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
regmap_16bit_config = &cs47l35_16bit_i2c_regmap;
regmap_32bit_config = &cs47l35_32bit_i2c_regmap;
}
break;
case CS47L85:
case WM1840:
if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
regmap_16bit_config = &cs47l85_16bit_i2c_regmap;
regmap_32bit_config = &cs47l85_32bit_i2c_regmap;
}
break;
case CS47L90:
case CS47L91:
if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
regmap_16bit_config = &cs47l90_16bit_i2c_regmap;
regmap_32bit_config = &cs47l90_32bit_i2c_regmap;
}
break;
default:
dev_err(&i2c->dev,
"Unknown Madera I2C device type %ld\n", type);
return -EINVAL;
}
name = madera_name_from_type(type);
if (!regmap_16bit_config) {
/* it's polite to say which codec isn't built into the kernel */
dev_err(&i2c->dev,
"Kernel does not include support for %s\n", name);
return -EINVAL;
}
madera = devm_kzalloc(&i2c->dev, sizeof(*madera), GFP_KERNEL);
if (!madera)
return -ENOMEM;
madera->regmap = devm_regmap_init_i2c(i2c, regmap_16bit_config);
if (IS_ERR(madera->regmap)) {
ret = PTR_ERR(madera->regmap);
dev_err(&i2c->dev,
"Failed to allocate 16-bit register map: %d\n", ret);
return ret;
}
madera->regmap_32bit = devm_regmap_init_i2c(i2c, regmap_32bit_config);
if (IS_ERR(madera->regmap_32bit)) {
ret = PTR_ERR(madera->regmap_32bit);
dev_err(&i2c->dev,
"Failed to allocate 32-bit register map: %d\n", ret);
return ret;
}
madera->type = type;
madera->type_name = name;
madera->dev = &i2c->dev;
madera->irq = i2c->irq;
return madera_dev_init(madera);
}
static int madera_i2c_remove(struct i2c_client *i2c)
{
struct madera *madera = dev_get_drvdata(&i2c->dev);
madera_dev_exit(madera);
return 0;
}
static const struct i2c_device_id madera_i2c_id[] = {
{ "cs47l35", CS47L35 },
{ "cs47l85", CS47L85 },
{ "cs47l90", CS47L90 },
{ "cs47l91", CS47L91 },
{ "wm1840", WM1840 },
{ }
};
MODULE_DEVICE_TABLE(i2c, madera_i2c_id);
static struct i2c_driver madera_i2c_driver = {
.driver = {
.name = "madera",
.pm = &madera_pm_ops,
.of_match_table = of_match_ptr(madera_of_match),
},
.probe = madera_i2c_probe,
.remove = madera_i2c_remove,
.id_table = madera_i2c_id,
};
module_i2c_driver(madera_i2c_driver);
MODULE_DESCRIPTION("Madera I2C bus interface");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* SPI bus interface to Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/mfd/madera/core.h>
#include "madera.h"
static int madera_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct madera *madera;
const struct regmap_config *regmap_16bit_config = NULL;
const struct regmap_config *regmap_32bit_config = NULL;
const void *of_data;
unsigned long type;
const char *name;
int ret;
of_data = of_device_get_match_data(&spi->dev);
if (of_data)
type = (unsigned long)of_data;
else
type = id->driver_data;
switch (type) {
case CS47L35:
if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
regmap_16bit_config = &cs47l35_16bit_spi_regmap;
regmap_32bit_config = &cs47l35_32bit_spi_regmap;
}
break;
case CS47L85:
case WM1840:
if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
regmap_16bit_config = &cs47l85_16bit_spi_regmap;
regmap_32bit_config = &cs47l85_32bit_spi_regmap;
}
break;
case CS47L90:
case CS47L91:
if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
regmap_16bit_config = &cs47l90_16bit_spi_regmap;
regmap_32bit_config = &cs47l90_32bit_spi_regmap;
}
break;
default:
dev_err(&spi->dev,
"Unknown Madera SPI device type %ld\n", type);
return -EINVAL;
}
name = madera_name_from_type(type);
if (!regmap_16bit_config) {
/* it's polite to say which codec isn't built into the kernel */
dev_err(&spi->dev,
"Kernel does not include support for %s\n", name);
return -EINVAL;
}
madera = devm_kzalloc(&spi->dev, sizeof(*madera), GFP_KERNEL);
if (!madera)
return -ENOMEM;
madera->regmap = devm_regmap_init_spi(spi, regmap_16bit_config);
if (IS_ERR(madera->regmap)) {
ret = PTR_ERR(madera->regmap);
dev_err(&spi->dev,
"Failed to allocate 16-bit register map: %d\n", ret);
return ret;
}
madera->regmap_32bit = devm_regmap_init_spi(spi, regmap_32bit_config);
if (IS_ERR(madera->regmap_32bit)) {
ret = PTR_ERR(madera->regmap_32bit);
dev_err(&spi->dev,
"Failed to allocate 32-bit register map: %d\n", ret);
return ret;
}
madera->type = type;
madera->type_name = name;
madera->dev = &spi->dev;
madera->irq = spi->irq;
return madera_dev_init(madera);
}
static int madera_spi_remove(struct spi_device *spi)
{
struct madera *madera = spi_get_drvdata(spi);
madera_dev_exit(madera);
return 0;
}
static const struct spi_device_id madera_spi_ids[] = {
{ "cs47l35", CS47L35 },
{ "cs47l85", CS47L85 },
{ "cs47l90", CS47L90 },
{ "cs47l91", CS47L91 },
{ "wm1840", WM1840 },
{ }
};
MODULE_DEVICE_TABLE(spi, madera_spi_ids);
static struct spi_driver madera_spi_driver = {
.driver = {
.name = "madera",
.pm = &madera_pm_ops,
.of_match_table = of_match_ptr(madera_of_match),
},
.probe = madera_spi_probe,
.remove = madera_spi_remove,
.id_table = madera_spi_ids,
};
module_spi_driver(madera_spi_driver);
MODULE_DESCRIPTION("Madera SPI bus interface");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL v2");
/*
* MFD internals for Cirrus Logic Madera codecs
*
* Copyright 2015-2018 Cirrus Logic
*
* 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 MADERA_MFD_H
#define MADERA_MFD_H
#include <linux/of.h>
#include <linux/pm.h>
struct madera;
extern const struct dev_pm_ops madera_pm_ops;
extern const struct of_device_id madera_of_match[];
int madera_dev_init(struct madera *madera);
int madera_dev_exit(struct madera *madera);
const char *madera_name_from_type(enum madera_type type);
extern const struct regmap_config cs47l35_16bit_spi_regmap;
extern const struct regmap_config cs47l35_32bit_spi_regmap;
extern const struct regmap_config cs47l35_16bit_i2c_regmap;
extern const struct regmap_config cs47l35_32bit_i2c_regmap;
int cs47l35_patch(struct madera *madera);
extern const struct regmap_config cs47l85_16bit_spi_regmap;
extern const struct regmap_config cs47l85_32bit_spi_regmap;
extern const struct regmap_config cs47l85_16bit_i2c_regmap;
extern const struct regmap_config cs47l85_32bit_i2c_regmap;
int cs47l85_patch(struct madera *madera);
extern const struct regmap_config cs47l90_16bit_spi_regmap;
extern const struct regmap_config cs47l90_32bit_spi_regmap;
extern const struct regmap_config cs47l90_16bit_i2c_regmap;
extern const struct regmap_config cs47l90_32bit_i2c_regmap;
int cs47l90_patch(struct madera *madera);
#endif
......@@ -63,16 +63,6 @@
#define RAVE_SP_TX_BUFFER_SIZE \
(RAVE_SP_STX_ETX_SIZE + 2 * RAVE_SP_RX_BUFFER_SIZE)
#define RAVE_SP_BOOT_SOURCE_GET 0
#define RAVE_SP_BOOT_SOURCE_SET 1
#define RAVE_SP_RDU2_BOARD_TYPE_RMB 0
#define RAVE_SP_RDU2_BOARD_TYPE_DEB 1
#define RAVE_SP_BOOT_SOURCE_SD 0
#define RAVE_SP_BOOT_SOURCE_EMMC 1
#define RAVE_SP_BOOT_SOURCE_NOR 2
/**
* enum rave_sp_deframer_state - Possible state for de-framer
*
......@@ -127,14 +117,44 @@ struct rave_sp_checksum {
void (*subroutine)(const u8 *, size_t, u8 *);
};
struct rave_sp_version {
u8 hardware;
__le16 major;
u8 minor;
u8 letter[2];
} __packed;
struct rave_sp_status {
struct rave_sp_version bootloader_version;
struct rave_sp_version firmware_version;
u16 rdu_eeprom_flag;
u16 dds_eeprom_flag;
u8 pic_flag;
u8 orientation;
u32 etc;
s16 temp[2];
u8 backlight_current[3];
u8 dip_switch;
u8 host_interrupt;
u16 voltage_28;
u8 i2c_device_status;
u8 power_status;
u8 general_status;
u8 deprecated1;
u8 power_led_status;
u8 deprecated2;
u8 periph_power_shutoff;
} __packed;
/**
* struct rave_sp_variant_cmds - Variant specific command routines
*
* @translate: Generic to variant specific command mapping routine
*
* @get_status: Variant specific implementation of CMD_GET_STATUS
*/
struct rave_sp_variant_cmds {
int (*translate)(enum rave_sp_command);
int (*get_status)(struct rave_sp *sp, struct rave_sp_status *);
};
/**
......@@ -180,35 +200,6 @@ struct rave_sp {
const char *part_number_bootloader;
};
struct rave_sp_version {
u8 hardware;
__le16 major;
u8 minor;
u8 letter[2];
} __packed;
struct rave_sp_status {
struct rave_sp_version bootloader_version;
struct rave_sp_version firmware_version;
u16 rdu_eeprom_flag;
u16 dds_eeprom_flag;
u8 pic_flag;
u8 orientation;
u32 etc;
s16 temp[2];
u8 backlight_current[3];
u8 dip_switch;
u8 host_interrupt;
u16 voltage_28;
u8 i2c_device_status;
u8 power_status;
u8 general_status;
u8 deprecated1;
u8 power_led_status;
u8 deprecated2;
u8 periph_power_shutoff;
} __packed;
static bool rave_sp_id_is_event(u8 code)
{
return (code & 0xF0) == RAVE_SP_EVNT_BASE;
......@@ -641,10 +632,14 @@ static int rave_sp_default_cmd_translate(enum rave_sp_command command)
return 0x14;
case RAVE_SP_CMD_SW_WDT:
return 0x1C;
case RAVE_SP_CMD_PET_WDT:
return 0x1D;
case RAVE_SP_CMD_RESET:
return 0x1E;
case RAVE_SP_CMD_RESET_REASON:
return 0x1F;
case RAVE_SP_CMD_RMB_EEPROM:
return 0x20;
default:
return -EINVAL;
}
......@@ -666,18 +661,44 @@ static const char *devm_rave_sp_version(struct device *dev,
version->letter[1]);
}
static int rave_sp_get_status(struct rave_sp *sp)
static int rave_sp_rdu1_get_status(struct rave_sp *sp,
struct rave_sp_status *status)
{
struct device *dev = &sp->serdev->dev;
u8 cmd[] = {
[0] = RAVE_SP_CMD_STATUS,
[1] = 0
};
return rave_sp_exec(sp, cmd, sizeof(cmd), status, sizeof(*status));
}
static int rave_sp_emulated_get_status(struct rave_sp *sp,
struct rave_sp_status *status)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_GET_FIRMWARE_VERSION,
[1] = 0,
};
int ret;
ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status->firmware_version,
sizeof(status->firmware_version));
if (ret)
return ret;
cmd[0] = RAVE_SP_CMD_GET_BOOTLOADER_VERSION;
return rave_sp_exec(sp, cmd, sizeof(cmd), &status->bootloader_version,
sizeof(status->bootloader_version));
}
static int rave_sp_get_status(struct rave_sp *sp)
{
struct device *dev = &sp->serdev->dev;
struct rave_sp_status status;
const char *version;
int ret;
ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status, sizeof(status));
ret = sp->variant->cmd.get_status(sp, &status);
if (ret)
return ret;
......@@ -707,9 +728,10 @@ static const struct rave_sp_checksum rave_sp_checksum_ccitt = {
};
static const struct rave_sp_variant rave_sp_legacy = {
.checksum = &rave_sp_checksum_8b2c,
.checksum = &rave_sp_checksum_ccitt,
.cmd = {
.translate = rave_sp_default_cmd_translate,
.get_status = rave_sp_emulated_get_status,
},
};
......@@ -717,6 +739,7 @@ static const struct rave_sp_variant rave_sp_rdu1 = {
.checksum = &rave_sp_checksum_8b2c,
.cmd = {
.translate = rave_sp_rdu1_cmd_translate,
.get_status = rave_sp_rdu1_get_status,
},
};
......@@ -724,6 +747,7 @@ static const struct rave_sp_variant rave_sp_rdu2 = {
.checksum = &rave_sp_checksum_ccitt,
.cmd = {
.translate = rave_sp_rdu2_cmd_translate,
.get_status = rave_sp_emulated_get_status,
},
};
......@@ -776,6 +800,13 @@ static int rave_sp_probe(struct serdev_device *serdev)
return ret;
serdev_device_set_baudrate(serdev, baud);
serdev_device_set_flow_control(serdev, false);
ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
if (ret) {
dev_err(dev, "Failed to set parity\n");
return ret;
}
ret = rave_sp_get_status(sp);
if (ret) {
......
// SPDX-License-Identifier: GPL-2.0-or-later
//
// Copyright (C) 2018 ROHM Semiconductors
//
// ROHM BD71837MWV PMIC driver
//
// Datasheet available from
// https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/mfd/rohm-bd718x7.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/regmap.h>
/*
* gpio_keys.h requires definiton of bool. It is brought in
* by above includes. Keep this as last until gpio_keys.h gets fixed.
*/
#include <linux/gpio_keys.h>
static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
static struct gpio_keys_button button = {
.code = KEY_POWER,
.gpio = -1,
.type = EV_KEY,
};
static struct gpio_keys_platform_data bd718xx_powerkey_data = {
.buttons = &button,
.nbuttons = 1,
.name = "bd718xx-pwrkey",
};
static struct mfd_cell bd71837_mfd_cells[] = {
{
.name = "gpio-keys",
.platform_data = &bd718xx_powerkey_data,
.pdata_size = sizeof(bd718xx_powerkey_data),
},
{ .name = "bd71837-clk", },
{ .name = "bd71837-pmic", },
};
static const struct regmap_irq bd71837_irqs[] = {
REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK),
REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK),
REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK),
REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK),
REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK),
REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK),
REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK),
};
static struct regmap_irq_chip bd71837_irq_chip = {
.name = "bd71837-irq",
.irqs = bd71837_irqs,
.num_irqs = ARRAY_SIZE(bd71837_irqs),
.num_regs = 1,
.irq_reg_stride = 1,
.status_base = BD71837_REG_IRQ,
.mask_base = BD71837_REG_MIRQ,
.ack_base = BD71837_REG_IRQ,
.init_ack_masked = true,
.mask_invert = false,
};
static const struct regmap_range pmic_status_range = {
.range_min = BD71837_REG_IRQ,
.range_max = BD71837_REG_POW_STATE,
};
static const struct regmap_access_table volatile_regs = {
.yes_ranges = &pmic_status_range,
.n_yes_ranges = 1,
};
static const struct regmap_config bd71837_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.volatile_table = &volatile_regs,
.max_register = BD71837_MAX_REGISTER - 1,
.cache_type = REGCACHE_RBTREE,
};
static int bd71837_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct bd71837 *bd71837;
int ret, i;
unsigned int val;
bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
if (!bd71837)
return -ENOMEM;
bd71837->chip_irq = i2c->irq;
if (!bd71837->chip_irq) {
dev_err(&i2c->dev, "No IRQ configured\n");
return -EINVAL;
}
bd71837->dev = &i2c->dev;
dev_set_drvdata(&i2c->dev, bd71837);
bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
if (IS_ERR(bd71837->regmap)) {
dev_err(&i2c->dev, "regmap initialization failed\n");
return PTR_ERR(bd71837->regmap);
}
ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val);
if (ret) {
dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n");
return ret;
}
for (i = 0; i < ARRAY_SIZE(supported_revisions); i++)
if (supported_revisions[i] == val)
break;
if (i == ARRAY_SIZE(supported_revisions)) {
dev_err(&i2c->dev, "Unsupported chip revision\n");
return -ENODEV;
}
ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
bd71837->chip_irq, IRQF_ONESHOT, 0,
&bd71837_irq_chip, &bd71837->irq_data);
if (ret) {
dev_err(&i2c->dev, "Failed to add irq_chip\n");
return ret;
}
/* Configure short press to 10 milliseconds */
ret = regmap_update_bits(bd71837->regmap,
BD71837_REG_PWRONCONFIG0,
BD718XX_PWRBTN_PRESS_DURATION_MASK,
BD718XX_PWRBTN_SHORT_PRESS_10MS);
if (ret) {
dev_err(&i2c->dev,
"Failed to configure button short press timeout\n");
return ret;
}
/* Configure long press to 10 seconds */
ret = regmap_update_bits(bd71837->regmap,
BD71837_REG_PWRONCONFIG1,
BD718XX_PWRBTN_PRESS_DURATION_MASK,
BD718XX_PWRBTN_LONG_PRESS_10S);
if (ret) {
dev_err(&i2c->dev,
"Failed to configure button long press timeout\n");
return ret;
}
ret = regmap_irq_get_virq(bd71837->irq_data, BD71837_INT_PWRBTN_S);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to get the IRQ\n");
return ret;
}
button.irq = ret;
ret = devm_mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
bd71837_mfd_cells,
ARRAY_SIZE(bd71837_mfd_cells), NULL, 0,
regmap_irq_get_domain(bd71837->irq_data));
if (ret)
dev_err(&i2c->dev, "Failed to create subdevices\n");
return ret;
}
static const struct of_device_id bd71837_of_match[] = {
{ .compatible = "rohm,bd71837", },
{ }
};
MODULE_DEVICE_TABLE(of, bd71837_of_match);
static struct i2c_driver bd71837_i2c_driver = {
.driver = {
.name = "rohm-bd718x7",
.of_match_table = bd71837_of_match,
},
.probe = bd71837_i2c_probe,
};
static int __init bd71837_i2c_init(void)
{
return i2c_add_driver(&bd71837_i2c_driver);
}
/* Initialise early so consumer devices can complete system boot */
subsys_initcall(bd71837_i2c_init);
static void __exit bd71837_i2c_exit(void)
{
i2c_del_driver(&bd71837_i2c_driver);
}
module_exit(bd71837_i2c_exit);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("ROHM BD71837 Power Management IC driver");
MODULE_LICENSE("GPL");
......@@ -146,6 +146,7 @@ static const struct of_device_id sec_dt_match[] = {
/* Sentinel */
},
};
MODULE_DEVICE_TABLE(of, sec_dt_match);
#endif
static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
......
......@@ -715,6 +715,7 @@ sm501_create_subdev(struct sm501_devdata *sm, char *name,
smdev->pdev.name = name;
smdev->pdev.id = sm->pdev_id;
smdev->pdev.dev.parent = sm->dev;
smdev->pdev.dev.coherent_dma_mask = 0xffffffff;
if (res_count) {
smdev->pdev.resource = (struct resource *)(smdev+1);
......
......@@ -209,14 +209,13 @@ static int ti_tscadc_probe(struct platform_device *pdev)
* The TSC_ADC_SS controller design assumes the OCP clock is
* at least 6x faster than the ADC clock.
*/
clk = clk_get(&pdev->dev, "adc_tsc_fck");
clk = devm_clk_get(&pdev->dev, "adc_tsc_fck");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed to get TSC fck\n");
err = PTR_ERR(clk);
goto err_disable_clk;
}
clock_rate = clk_get_rate(clk);
clk_put(clk);
tscadc->clk_div = clock_rate / ADC_CLK;
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
......
......@@ -302,6 +302,10 @@ static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
if (of_find_property(np, "wlf,ldoena-always-driven", NULL))
pdata->lineout2fb = true;
pdata->spkmode_pu = of_property_read_bool(np, "wlf,spkmode-pu");
pdata->csnaddr_pd = of_property_read_bool(np, "wlf,csnaddr-pd");
pdata->ldo[0].enable = of_get_named_gpio(np, "wlf,ldo1ena", 0);
if (pdata->ldo[0].enable < 0)
pdata->ldo[0].enable = 0;
......@@ -513,14 +517,15 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
break;
default:
dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
return -EINVAL;
ret = -EINVAL;
goto err_enable;
}
ret = regmap_reinit_cache(wm8994->regmap, regmap_config);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to reinit register cache: %d\n",
ret);
return ret;
goto err_enable;
}
/* Explicitly put the device into reset in case regulators
......@@ -531,7 +536,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
if (ret != 0) {
dev_err(wm8994->dev, "Failed to reset device: %d\n", ret);
return ret;
goto err_enable;
}
if (regmap_patch) {
......@@ -540,7 +545,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
if (ret != 0) {
dev_err(wm8994->dev, "Failed to register patch: %d\n",
ret);
goto err;
goto err_enable;
}
}
......@@ -559,6 +564,8 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
if (pdata->spkmode_pu)
pulls |= WM8994_SPKMODE_PU;
if (pdata->csnaddr_pd)
pulls |= WM8994_CSNADDR_PD;
/* Disable unneeded pulls */
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
......
......@@ -361,6 +361,7 @@ source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/zte/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
source "drivers/pinctrl/cirrus/Kconfig"
config PINCTRL_XWAY
bool
......
......@@ -64,3 +64,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-y += mediatek/
obj-$(CONFIG_PINCTRL_ZX) += zte/
obj-y += cirrus/
# This is all selected by the Madera MFD driver Kconfig options
config PINCTRL_MADERA
tristate
select PINMUX
select GENERIC_PINCONF
config PINCTRL_CS47L35
bool
config PINCTRL_CS47L85
bool
config PINCTRL_CS47L90
bool
# Cirrus Logic pinctrl drivers
pinctrl-madera-objs := pinctrl-madera-core.o
ifeq ($(CONFIG_PINCTRL_CS47L35),y)
pinctrl-madera-objs += pinctrl-cs47l35.o
endif
ifeq ($(CONFIG_PINCTRL_CS47L85),y)
pinctrl-madera-objs += pinctrl-cs47l85.o
endif
ifeq ($(CONFIG_PINCTRL_CS47L90),y)
pinctrl-madera-objs += pinctrl-cs47l90.o
endif
obj-$(CONFIG_PINCTRL_MADERA) += pinctrl-madera.o
// SPDX-License-Identifier: GPL-2.0
/*
* Pinctrl for Cirrus Logic CS47L35
*
* Copyright (C) 2016-2017 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/err.h>
#include <linux/mfd/madera/core.h>
#include "pinctrl-madera.h"
/*
* The alt func groups are the most commonly used functions we place these at
* the lower function indexes for convenience, and the less commonly used gpio
* functions at higher indexes.
*
* To stay consistent with the datasheet the function names are the same as
* the group names for that function's pins
*
* Note - all 1 less than in datasheet because these are zero-indexed
*/
static const unsigned int cs47l35_aif3_pins[] = { 0, 1, 2, 3 };
static const unsigned int cs47l35_spk_pins[] = { 4, 5 };
static const unsigned int cs47l35_aif1_pins[] = { 7, 8, 9, 10 };
static const unsigned int cs47l35_aif2_pins[] = { 11, 12, 13, 14 };
static const unsigned int cs47l35_mif1_pins[] = { 6, 15 };
static const struct madera_pin_groups cs47l35_pin_groups[] = {
{ "aif1", cs47l35_aif1_pins, ARRAY_SIZE(cs47l35_aif1_pins) },
{ "aif2", cs47l35_aif2_pins, ARRAY_SIZE(cs47l35_aif2_pins) },
{ "aif3", cs47l35_aif3_pins, ARRAY_SIZE(cs47l35_aif3_pins) },
{ "mif1", cs47l35_mif1_pins, ARRAY_SIZE(cs47l35_mif1_pins) },
{ "pdmspk1", cs47l35_spk_pins, ARRAY_SIZE(cs47l35_spk_pins) },
};
const struct madera_pin_chip cs47l35_pin_chip = {
.n_pins = CS47L35_NUM_GPIOS,
.pin_groups = cs47l35_pin_groups,
.n_pin_groups = ARRAY_SIZE(cs47l35_pin_groups),
};
// SPDX-License-Identifier: GPL-2.0
/*
* Pinctrl for Cirrus Logic CS47L85
*
* Copyright (C) 2016-2017 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/err.h>
#include <linux/mfd/madera/core.h>
#include "pinctrl-madera.h"
/*
* The alt func groups are the most commonly used functions we place these at
* the lower function indexes for convenience, and the less commonly used gpio
* functions at higher indexes.
*
* To stay consistent with the datasheet the function names are the same as
* the group names for that function's pins
*
* Note - all 1 less than in datasheet because these are zero-indexed
*/
static const unsigned int cs47l85_mif1_pins[] = { 8, 9 };
static const unsigned int cs47l85_mif2_pins[] = { 10, 11 };
static const unsigned int cs47l85_mif3_pins[] = { 12, 13 };
static const unsigned int cs47l85_aif1_pins[] = { 14, 15, 16, 17 };
static const unsigned int cs47l85_aif2_pins[] = { 18, 19, 20, 21 };
static const unsigned int cs47l85_aif3_pins[] = { 22, 23, 24, 25 };
static const unsigned int cs47l85_aif4_pins[] = { 26, 27, 28, 29 };
static const unsigned int cs47l85_dmic4_pins[] = { 30, 31 };
static const unsigned int cs47l85_dmic5_pins[] = { 32, 33 };
static const unsigned int cs47l85_dmic6_pins[] = { 34, 35 };
static const unsigned int cs47l85_spk1_pins[] = { 36, 38 };
static const unsigned int cs47l85_spk2_pins[] = { 37, 39 };
static const struct madera_pin_groups cs47l85_pin_groups[] = {
{ "aif1", cs47l85_aif1_pins, ARRAY_SIZE(cs47l85_aif1_pins) },
{ "aif2", cs47l85_aif2_pins, ARRAY_SIZE(cs47l85_aif2_pins) },
{ "aif3", cs47l85_aif3_pins, ARRAY_SIZE(cs47l85_aif3_pins) },
{ "aif4", cs47l85_aif4_pins, ARRAY_SIZE(cs47l85_aif4_pins) },
{ "mif1", cs47l85_mif1_pins, ARRAY_SIZE(cs47l85_mif1_pins) },
{ "mif2", cs47l85_mif2_pins, ARRAY_SIZE(cs47l85_mif2_pins) },
{ "mif3", cs47l85_mif3_pins, ARRAY_SIZE(cs47l85_mif3_pins) },
{ "dmic4", cs47l85_dmic4_pins, ARRAY_SIZE(cs47l85_dmic4_pins) },
{ "dmic5", cs47l85_dmic5_pins, ARRAY_SIZE(cs47l85_dmic5_pins) },
{ "dmic6", cs47l85_dmic6_pins, ARRAY_SIZE(cs47l85_dmic6_pins) },
{ "pdmspk1", cs47l85_spk1_pins, ARRAY_SIZE(cs47l85_spk1_pins) },
{ "pdmspk2", cs47l85_spk2_pins, ARRAY_SIZE(cs47l85_spk2_pins) },
};
const struct madera_pin_chip cs47l85_pin_chip = {
.n_pins = CS47L85_NUM_GPIOS,
.pin_groups = cs47l85_pin_groups,
.n_pin_groups = ARRAY_SIZE(cs47l85_pin_groups),
};
// SPDX-License-Identifier: GPL-2.0
/*
* Pinctrl for Cirrus Logic CS47L90
*
* Copyright (C) 2016-2017 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/err.h>
#include <linux/mfd/madera/core.h>
#include "pinctrl-madera.h"
/*
* The alt func groups are the most commonly used functions we place these at
* the lower function indexes for convenience, and the less commonly used gpio
* functions at higher indexes.
*
* To stay consistent with the datasheet the function names are the same as
* the group names for that function's pins
*
* Note - all 1 less than in datasheet because these are zero-indexed
*/
static const unsigned int cs47l90_mif1_pins[] = { 8, 9 };
static const unsigned int cs47l90_mif2_pins[] = { 10, 11 };
static const unsigned int cs47l90_mif3_pins[] = { 12, 13 };
static const unsigned int cs47l90_aif1_pins[] = { 14, 15, 16, 17 };
static const unsigned int cs47l90_aif2_pins[] = { 18, 19, 20, 21 };
static const unsigned int cs47l90_aif3_pins[] = { 22, 23, 24, 25 };
static const unsigned int cs47l90_aif4_pins[] = { 26, 27, 28, 29 };
static const unsigned int cs47l90_dmic4_pins[] = { 30, 31 };
static const unsigned int cs47l90_dmic5_pins[] = { 32, 33 };
static const unsigned int cs47l90_dmic3_pins[] = { 34, 35 };
static const unsigned int cs47l90_spk1_pins[] = { 36, 37 };
static const struct madera_pin_groups cs47l90_pin_groups[] = {
{ "aif1", cs47l90_aif1_pins, ARRAY_SIZE(cs47l90_aif1_pins) },
{ "aif2", cs47l90_aif2_pins, ARRAY_SIZE(cs47l90_aif2_pins) },
{ "aif3", cs47l90_aif3_pins, ARRAY_SIZE(cs47l90_aif3_pins) },
{ "aif4", cs47l90_aif4_pins, ARRAY_SIZE(cs47l90_aif4_pins) },
{ "mif1", cs47l90_mif1_pins, ARRAY_SIZE(cs47l90_mif1_pins) },
{ "mif2", cs47l90_mif2_pins, ARRAY_SIZE(cs47l90_mif2_pins) },
{ "mif3", cs47l90_mif3_pins, ARRAY_SIZE(cs47l90_mif3_pins) },
{ "dmic3", cs47l90_dmic3_pins, ARRAY_SIZE(cs47l90_dmic3_pins) },
{ "dmic4", cs47l90_dmic4_pins, ARRAY_SIZE(cs47l90_dmic4_pins) },
{ "dmic5", cs47l90_dmic5_pins, ARRAY_SIZE(cs47l90_dmic5_pins) },
{ "pdmspk1", cs47l90_spk1_pins, ARRAY_SIZE(cs47l90_spk1_pins) },
};
const struct madera_pin_chip cs47l90_pin_chip = {
.n_pins = CS47L90_NUM_GPIOS,
.pin_groups = cs47l90_pin_groups,
.n_pin_groups = ARRAY_SIZE(cs47l90_pin_groups),
};
// SPDX-License-Identifier: GPL-2.0
/*
* Pinctrl for Cirrus Logic Madera codecs
*
* Copyright (C) 2016-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/mfd/madera/core.h>
#include <linux/mfd/madera/registers.h>
#include "../pinctrl-utils.h"
#include "pinctrl-madera.h"
/*
* Use pin GPIO names for consistency
* NOTE: IDs are zero-indexed for coding convenience
*/
static const struct pinctrl_pin_desc madera_pins[] = {
PINCTRL_PIN(0, "gpio1"),
PINCTRL_PIN(1, "gpio2"),
PINCTRL_PIN(2, "gpio3"),
PINCTRL_PIN(3, "gpio4"),
PINCTRL_PIN(4, "gpio5"),
PINCTRL_PIN(5, "gpio6"),
PINCTRL_PIN(6, "gpio7"),
PINCTRL_PIN(7, "gpio8"),
PINCTRL_PIN(8, "gpio9"),
PINCTRL_PIN(9, "gpio10"),
PINCTRL_PIN(10, "gpio11"),
PINCTRL_PIN(11, "gpio12"),
PINCTRL_PIN(12, "gpio13"),
PINCTRL_PIN(13, "gpio14"),
PINCTRL_PIN(14, "gpio15"),
PINCTRL_PIN(15, "gpio16"),
PINCTRL_PIN(16, "gpio17"),
PINCTRL_PIN(17, "gpio18"),
PINCTRL_PIN(18, "gpio19"),
PINCTRL_PIN(19, "gpio20"),
PINCTRL_PIN(20, "gpio21"),
PINCTRL_PIN(21, "gpio22"),
PINCTRL_PIN(22, "gpio23"),
PINCTRL_PIN(23, "gpio24"),
PINCTRL_PIN(24, "gpio25"),
PINCTRL_PIN(25, "gpio26"),
PINCTRL_PIN(26, "gpio27"),
PINCTRL_PIN(27, "gpio28"),
PINCTRL_PIN(28, "gpio29"),
PINCTRL_PIN(29, "gpio30"),
PINCTRL_PIN(30, "gpio31"),
PINCTRL_PIN(31, "gpio32"),
PINCTRL_PIN(32, "gpio33"),
PINCTRL_PIN(33, "gpio34"),
PINCTRL_PIN(34, "gpio35"),
PINCTRL_PIN(35, "gpio36"),
PINCTRL_PIN(36, "gpio37"),
PINCTRL_PIN(37, "gpio38"),
PINCTRL_PIN(38, "gpio39"),
PINCTRL_PIN(39, "gpio40"),
};
/*
* All single-pin functions can be mapped to any GPIO, however pinmux applies
* functions to pin groups and only those groups declared as supporting that
* function. To make this work we must put each pin in its own dummy group so
* that the functions can be described as applying to all pins.
* Since these do not correspond to anything in the actual hardware - they are
* merely an adaptation to pinctrl's view of the world - we use the same name
* as the pin to avoid confusion when comparing with datasheet instructions
*/
static const char * const madera_pin_single_group_names[] = {
"gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
};
/* set of pin numbers for single-pin groups, zero-indexed */
static const unsigned int madera_pin_single_group_pins[] = {
0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39,
};
static const char * const madera_aif1_group_names[] = { "aif1" };
static const char * const madera_aif2_group_names[] = { "aif2" };
static const char * const madera_aif3_group_names[] = { "aif3" };
static const char * const madera_aif4_group_names[] = { "aif4" };
static const char * const madera_mif1_group_names[] = { "mif1" };
static const char * const madera_mif2_group_names[] = { "mif2" };
static const char * const madera_mif3_group_names[] = { "mif3" };
static const char * const madera_dmic3_group_names[] = { "dmic3" };
static const char * const madera_dmic4_group_names[] = { "dmic4" };
static const char * const madera_dmic5_group_names[] = { "dmic5" };
static const char * const madera_dmic6_group_names[] = { "dmic6" };
static const char * const madera_spk1_group_names[] = { "pdmspk1" };
static const char * const madera_spk2_group_names[] = { "pdmspk2" };
/*
* alt-functions always apply to a single pin group, other functions always
* apply to all pins
*/
static const struct {
const char *name;
const char * const *group_names;
u32 func;
} madera_mux_funcs[] = {
{
.name = "aif1",
.group_names = madera_aif1_group_names,
.func = 0x000
},
{
.name = "aif2",
.group_names = madera_aif2_group_names,
.func = 0x000
},
{
.name = "aif3",
.group_names = madera_aif3_group_names,
.func = 0x000
},
{
.name = "aif4",
.group_names = madera_aif4_group_names,
.func = 0x000
},
{
.name = "mif1",
.group_names = madera_mif1_group_names,
.func = 0x000
},
{
.name = "mif2",
.group_names = madera_mif2_group_names,
.func = 0x000
},
{
.name = "mif3",
.group_names = madera_mif3_group_names,
.func = 0x000
},
{
.name = "dmic3",
.group_names = madera_dmic3_group_names,
.func = 0x000
},
{
.name = "dmic4",
.group_names = madera_dmic4_group_names,
.func = 0x000
},
{
.name = "dmic5",
.group_names = madera_dmic5_group_names,
.func = 0x000
},
{
.name = "dmic6",
.group_names = madera_dmic6_group_names,
.func = 0x000
},
{
.name = "pdmspk1",
.group_names = madera_spk1_group_names,
.func = 0x000
},
{
.name = "pdmspk2",
.group_names = madera_spk2_group_names,
.func = 0x000
},
{
.name = "io",
.group_names = madera_pin_single_group_names,
.func = 0x001
},
{
.name = "dsp-gpio",
.group_names = madera_pin_single_group_names,
.func = 0x002
},
{
.name = "irq1",
.group_names = madera_pin_single_group_names,
.func = 0x003
},
{
.name = "irq2",
.group_names = madera_pin_single_group_names,
.func = 0x004
},
{
.name = "fll1-clk",
.group_names = madera_pin_single_group_names,
.func = 0x010
},
{
.name = "fll2-clk",
.group_names = madera_pin_single_group_names,
.func = 0x011
},
{
.name = "fll3-clk",
.group_names = madera_pin_single_group_names,
.func = 0x012
},
{
.name = "fllao-clk",
.group_names = madera_pin_single_group_names,
.func = 0x013
},
{
.name = "fll1-lock",
.group_names = madera_pin_single_group_names,
.func = 0x018
},
{
.name = "fll2-lock",
.group_names = madera_pin_single_group_names,
.func = 0x019
},
{
.name = "fll3-lock",
.group_names = madera_pin_single_group_names,
.func = 0x01a
},
{
.name = "fllao-lock",
.group_names = madera_pin_single_group_names,
.func = 0x01b
},
{
.name = "opclk",
.group_names = madera_pin_single_group_names,
.func = 0x040
},
{
.name = "opclk-async",
.group_names = madera_pin_single_group_names,
.func = 0x041
},
{
.name = "pwm1",
.group_names = madera_pin_single_group_names,
.func = 0x048
},
{
.name = "pwm2",
.group_names = madera_pin_single_group_names,
.func = 0x049
},
{
.name = "spdif",
.group_names = madera_pin_single_group_names,
.func = 0x04c
},
{
.name = "asrc1-in1-lock",
.group_names = madera_pin_single_group_names,
.func = 0x088
},
{
.name = "asrc1-in2-lock",
.group_names = madera_pin_single_group_names,
.func = 0x089
},
{
.name = "asrc2-in1-lock",
.group_names = madera_pin_single_group_names,
.func = 0x08a
},
{
.name = "asrc2-in2-lock",
.group_names = madera_pin_single_group_names,
.func = 0x08b
},
{
.name = "spkl-short-circuit",
.group_names = madera_pin_single_group_names,
.func = 0x0b6
},
{
.name = "spkr-short-circuit",
.group_names = madera_pin_single_group_names,
.func = 0x0b7
},
{
.name = "spk-shutdown",
.group_names = madera_pin_single_group_names,
.func = 0x0e0
},
{
.name = "spk-overheat-shutdown",
.group_names = madera_pin_single_group_names,
.func = 0x0e1
},
{
.name = "spk-overheat-warn",
.group_names = madera_pin_single_group_names,
.func = 0x0e2
},
{
.name = "timer1-sts",
.group_names = madera_pin_single_group_names,
.func = 0x140
},
{
.name = "timer2-sts",
.group_names = madera_pin_single_group_names,
.func = 0x141
},
{
.name = "timer3-sts",
.group_names = madera_pin_single_group_names,
.func = 0x142
},
{
.name = "timer4-sts",
.group_names = madera_pin_single_group_names,
.func = 0x143
},
{
.name = "timer5-sts",
.group_names = madera_pin_single_group_names,
.func = 0x144
},
{
.name = "timer6-sts",
.group_names = madera_pin_single_group_names,
.func = 0x145
},
{
.name = "timer7-sts",
.group_names = madera_pin_single_group_names,
.func = 0x146
},
{
.name = "timer8-sts",
.group_names = madera_pin_single_group_names,
.func = 0x147
},
{
.name = "log1-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x150
},
{
.name = "log2-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x151
},
{
.name = "log3-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x152
},
{
.name = "log4-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x153
},
{
.name = "log5-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x154
},
{
.name = "log6-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x155
},
{
.name = "log7-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x156
},
{
.name = "log8-fifo-ne",
.group_names = madera_pin_single_group_names,
.func = 0x157
},
};
static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
unsigned int milliamps)
{
switch (milliamps) {
case 4:
return 0;
case 8:
return 2 << MADERA_GP1_DRV_STR_SHIFT;
default:
break;
}
dev_warn(priv->dev, "%u mA not a valid drive strength", milliamps);
return 0;
}
static unsigned int madera_pin_unmake_drv_str(struct madera_pin_private *priv,
u16 regval)
{
regval = (regval & MADERA_GP1_DRV_STR_MASK) >> MADERA_GP1_DRV_STR_SHIFT;
switch (regval) {
case 0:
return 4;
case 2:
return 8;
default:
return 0;
}
}
static int madera_get_groups_count(struct pinctrl_dev *pctldev)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
/* Number of alt function groups plus number of single-pin groups */
return priv->chip->n_pin_groups + priv->chip->n_pins;
}
static const char *madera_get_group_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
if (selector < priv->chip->n_pin_groups)
return priv->chip->pin_groups[selector].name;
selector -= priv->chip->n_pin_groups;
return madera_pin_single_group_names[selector];
}
static int madera_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector,
const unsigned int **pins,
unsigned int *num_pins)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
if (selector < priv->chip->n_pin_groups) {
*pins = priv->chip->pin_groups[selector].pins;
*num_pins = priv->chip->pin_groups[selector].n_pins;
} else {
/* return the dummy group for a single pin */
selector -= priv->chip->n_pin_groups;
*pins = &madera_pin_single_group_pins[selector];
*num_pins = 1;
}
return 0;
}
static void madera_pin_dbg_show_fn(struct madera_pin_private *priv,
struct seq_file *s,
unsigned int pin, unsigned int fn)
{
const struct madera_pin_chip *chip = priv->chip;
int i, g_pin;
if (fn != 0) {
for (i = 0; i < ARRAY_SIZE(madera_mux_funcs); ++i) {
if (madera_mux_funcs[i].func == fn) {
seq_printf(s, " FN=%s",
madera_mux_funcs[i].name);
return;
}
}
return; /* ignore unknown function values */
}
/* alt function */
for (i = 0; i < chip->n_pin_groups; ++i) {
for (g_pin = 0; g_pin < chip->pin_groups[i].n_pins; ++g_pin) {
if (chip->pin_groups[i].pins[g_pin] == pin) {
seq_printf(s, " FN=%s",
chip->pin_groups[i].name);
return;
}
}
}
}
static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned int pin)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int conf[2];
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
unsigned int fn;
int ret;
ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
if (ret)
return;
ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
if (ret)
return;
seq_printf(s, "%04x:%04x", conf[0], conf[1]);
fn = (conf[0] & MADERA_GP1_FN_MASK) >> MADERA_GP1_FN_SHIFT;
madera_pin_dbg_show_fn(priv, s, pin, fn);
/* State of direction bit is only relevant if function==1 */
if (fn == 1) {
if (conf[1] & MADERA_GP1_DIR_MASK)
seq_puts(s, " IN");
else
seq_puts(s, " OUT");
}
if (conf[1] & MADERA_GP1_PU_MASK)
seq_puts(s, " PU");
if (conf[1] & MADERA_GP1_PD_MASK)
seq_puts(s, " PD");
if (conf[0] & MADERA_GP1_DB_MASK)
seq_puts(s, " DB");
if (conf[0] & MADERA_GP1_OP_CFG_MASK)
seq_puts(s, " OD");
else
seq_puts(s, " CMOS");
seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
if (conf[0] & MADERA_GP1_IP_CFG_MASK)
seq_puts(s, "SCHMITT");
}
static const struct pinctrl_ops madera_pin_group_ops = {
.get_groups_count = madera_get_groups_count,
.get_group_name = madera_get_group_name,
.get_group_pins = madera_get_group_pins,
#if IS_ENABLED(CONFIG_OF)
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinctrl_utils_free_map,
#endif
#if IS_ENABLED(CONFIG_DEBUG_FS)
.pin_dbg_show = madera_pin_dbg_show,
#endif
};
static int madera_mux_get_funcs_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(madera_mux_funcs);
}
static const char *madera_mux_get_func_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
return madera_mux_funcs[selector].name;
}
static int madera_mux_get_groups(struct pinctrl_dev *pctldev,
unsigned int selector,
const char * const **groups,
unsigned int * const num_groups)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
*groups = madera_mux_funcs[selector].group_names;
if (madera_mux_funcs[selector].func == 0) {
/* alt func always maps to a single group */
*num_groups = 1;
} else {
/* other funcs map to all available gpio pins */
*num_groups = priv->chip->n_pins;
}
return 0;
}
static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned int group)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
struct madera *madera = priv->madera;
const struct madera_pin_groups *pin_group = priv->chip->pin_groups;
unsigned int n_chip_groups = priv->chip->n_pin_groups;
const char *func_name = madera_mux_funcs[selector].name;
unsigned int reg;
int i, ret;
dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
__func__, selector, func_name, group,
madera_get_group_name(pctldev, group));
if (madera_mux_funcs[selector].func == 0) {
/* alt func pin assignments are codec-specific */
for (i = 0; i < n_chip_groups; ++i) {
if (strcmp(func_name, pin_group->name) == 0)
break;
++pin_group;
}
if (i == n_chip_groups)
return -EINVAL;
for (i = 0; i < pin_group->n_pins; ++i) {
reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
__func__, reg);
ret = regmap_update_bits(madera->regmap, reg,
MADERA_GP1_FN_MASK, 0);
if (ret)
break;
}
} else {
/*
* for other funcs the group will be the gpio number and will
* be offset by the number of chip-specific functions at the
* start of the group list
*/
group -= n_chip_groups;
reg = MADERA_GPIO1_CTRL_1 + (2 * group);
dev_dbg(priv->dev, "%s setting 0x%x func bits to 0x%x\n",
__func__, reg, madera_mux_funcs[selector].func);
ret = regmap_update_bits(madera->regmap,
reg,
MADERA_GP1_FN_MASK,
madera_mux_funcs[selector].func);
}
if (ret)
dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
return ret;
}
static int madera_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset,
bool input)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
struct madera *madera = priv->madera;
unsigned int reg = MADERA_GPIO1_CTRL_2 + (2 * offset);
unsigned int val;
int ret;
if (input)
val = MADERA_GP1_DIR;
else
val = 0;
ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_DIR_MASK, val);
if (ret)
dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
return ret;
}
static int madera_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
struct madera *madera = priv->madera;
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
int ret;
/* put the pin into GPIO mode */
ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
if (ret)
dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
return ret;
}
static void madera_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
struct madera *madera = priv->madera;
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
int ret;
/* disable GPIO by setting to GPIO IN */
madera_gpio_set_direction(pctldev, range, offset, true);
ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
if (ret)
dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
}
static const struct pinmux_ops madera_pin_mux_ops = {
.get_functions_count = madera_mux_get_funcs_count,
.get_function_name = madera_mux_get_func_name,
.get_function_groups = madera_mux_get_groups,
.set_mux = madera_mux_set_mux,
.gpio_request_enable = madera_gpio_request_enable,
.gpio_disable_free = madera_gpio_disable_free,
.gpio_set_direction = madera_gpio_set_direction,
.strict = true, /* GPIO and other functions are exclusive */
};
static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int param = pinconf_to_config_param(*config);
unsigned int result = 0;
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
unsigned int conf[2];
int ret;
ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
if (!ret)
ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
if (ret) {
dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
pin + 1, ret);
return ret;
}
switch (param) {
case PIN_CONFIG_BIAS_BUS_HOLD:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
result = 1;
break;
case PIN_CONFIG_BIAS_DISABLE:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
if (!conf[1])
result = 1;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
if (conf[1] == MADERA_GP1_PD_MASK)
result = 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
if (conf[1] == MADERA_GP1_PU_MASK)
result = 1;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
if (conf[0] & MADERA_GP1_OP_CFG_MASK)
result = 1;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
result = 1;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
result = madera_pin_unmake_drv_str(priv, conf[1]);
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
if (conf[0] & MADERA_GP1_DB_MASK)
result = 1;
break;
case PIN_CONFIG_INPUT_ENABLE:
if (conf[0] & MADERA_GP1_DIR_MASK)
result = 1;
break;
case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if (conf[0] & MADERA_GP1_IP_CFG_MASK)
result = 1;
break;
case PIN_CONFIG_OUTPUT:
if ((conf[1] & MADERA_GP1_DIR_MASK) &&
(conf[0] & MADERA_GP1_LVL_MASK))
result = 1;
break;
default:
break;
}
*config = pinconf_to_config_packed(param, result);
return 0;
}
static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
u16 conf[2] = {0, 0};
u16 mask[2] = {0, 0};
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
unsigned int val;
int ret;
while (num_configs) {
dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
switch (pinconf_to_config_param(*configs)) {
case PIN_CONFIG_BIAS_BUS_HOLD:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
break;
case PIN_CONFIG_BIAS_DISABLE:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PD;
conf[1] &= ~MADERA_GP1_PU;
break;
case PIN_CONFIG_BIAS_PULL_UP:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PU;
conf[1] &= ~MADERA_GP1_PD;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
mask[0] |= MADERA_GP1_OP_CFG_MASK;
conf[0] |= MADERA_GP1_OP_CFG;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
mask[0] |= MADERA_GP1_OP_CFG_MASK;
conf[0] &= ~MADERA_GP1_OP_CFG;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
val = pinconf_to_config_argument(*configs);
mask[1] |= MADERA_GP1_DRV_STR_MASK;
conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
conf[1] |= madera_pin_make_drv_str(priv, val);
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
mask[0] |= MADERA_GP1_DB_MASK;
/*
* we can't configure debounce time per-pin so value
* is just a flag
*/
val = pinconf_to_config_argument(*configs);
if (val)
conf[0] |= MADERA_GP1_DB;
else
conf[0] &= ~MADERA_GP1_DB;
break;
case PIN_CONFIG_INPUT_ENABLE:
val = pinconf_to_config_argument(*configs);
mask[1] |= MADERA_GP1_DIR_MASK;
if (val)
conf[1] |= MADERA_GP1_DIR;
else
conf[1] &= ~MADERA_GP1_DIR;
break;
case PIN_CONFIG_INPUT_SCHMITT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_IP_CFG;
if (val)
conf[0] |= MADERA_GP1_IP_CFG;
else
conf[0] &= ~MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
mask[0] |= MADERA_GP1_IP_CFG;
conf[0] |= MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR;
break;
case PIN_CONFIG_OUTPUT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_LVL_MASK;
if (val)
conf[0] |= MADERA_GP1_LVL;
else
conf[0] &= ~MADERA_GP1_LVL;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] &= ~MADERA_GP1_DIR;
break;
default:
break;
}
++configs;
--num_configs;
}
dev_dbg(priv->dev,
"%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
__func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
if (ret)
goto err;
++reg;
ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
if (ret)
goto err;
return 0;
err:
dev_err(priv->dev,
"Failed to write GPIO%d conf (%d) reg 0x%x\n",
pin + 1, ret, reg);
return ret;
}
static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
const struct madera_pin_groups *pin_group;
unsigned int n_groups = priv->chip->n_pin_groups;
int i, ret;
dev_dbg(priv->dev, "%s setting group %s\n", __func__,
madera_get_group_name(pctldev, selector));
if (selector >= n_groups) {
/* group is a single pin, convert to pin number and set */
return madera_pin_conf_set(pctldev,
selector - n_groups,
configs,
num_configs);
} else {
pin_group = &priv->chip->pin_groups[selector];
for (i = 0; i < pin_group->n_pins; ++i) {
ret = madera_pin_conf_set(pctldev,
pin_group->pins[i],
configs,
num_configs);
if (ret)
return ret;
}
}
return 0;
}
static const struct pinconf_ops madera_pin_conf_ops = {
.pin_config_get = madera_pin_conf_get,
.pin_config_set = madera_pin_conf_set,
.pin_config_group_set = madera_pin_conf_group_set,
};
static struct pinctrl_desc madera_pin_desc = {
.name = "madera-pinctrl",
.pins = madera_pins,
.pctlops = &madera_pin_group_ops,
.pmxops = &madera_pin_mux_ops,
.confops = &madera_pin_conf_ops,
.owner = THIS_MODULE,
};
static int madera_pin_probe(struct platform_device *pdev)
{
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
const struct madera_pdata *pdata = dev_get_platdata(madera->dev);
struct madera_pin_private *priv;
int ret;
BUILD_BUG_ON(ARRAY_SIZE(madera_pin_single_group_names) !=
ARRAY_SIZE(madera_pin_single_group_pins));
dev_dbg(&pdev->dev, "%s\n", __func__);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = &pdev->dev;
priv->madera = madera;
pdev->dev.of_node = madera->dev->of_node;
switch (madera->type) {
case CS47L35:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
priv->chip = &cs47l35_pin_chip;
break;
case CS47L85:
case WM1840:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
priv->chip = &cs47l85_pin_chip;
break;
case CS47L90:
case CS47L91:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
priv->chip = &cs47l90_pin_chip;
break;
default:
break;
}
if (!priv->chip)
return -ENODEV;
madera_pin_desc.npins = priv->chip->n_pins;
ret = devm_pinctrl_register_and_init(&pdev->dev,
&madera_pin_desc,
priv,
&priv->pctl);
if (ret) {
dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret);
return ret;
}
/* if the configuration is provided through pdata, apply it */
if (pdata) {
ret = pinctrl_register_mappings(pdata->gpio_configs,
pdata->n_gpio_configs);
if (ret) {
dev_err(priv->dev,
"Failed to register pdata mappings (%d)\n",
ret);
return ret;
}
}
ret = pinctrl_enable(priv->pctl);
if (ret) {
dev_err(priv->dev, "Failed to enable pinctrl (%d)\n", ret);
return ret;
}
dev_dbg(priv->dev, "pinctrl probed ok\n");
return 0;
}
static struct platform_driver madera_pin_driver = {
.probe = madera_pin_probe,
.driver = {
.name = "madera-pinctrl",
},
};
module_platform_driver(madera_pin_driver);
MODULE_DESCRIPTION("Madera pinctrl driver");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Pinctrl for Cirrus Logic Madera codecs
*
* Copyright (C) 2016-2017 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#ifndef PINCTRL_MADERA_H
#define PINCTRL_MADERA_H
struct madera_pin_groups {
const char *name;
const unsigned int *pins;
unsigned int n_pins;
};
struct madera_pin_chip {
unsigned int n_pins;
const struct madera_pin_groups *pin_groups;
unsigned int n_pin_groups;
};
struct madera_pin_private {
struct madera *madera;
const struct madera_pin_chip *chip; /* chip-specific groups */
struct device *dev;
struct pinctrl_dev *pctl;
};
extern const struct madera_pin_chip cs47l35_pin_chip;
extern const struct madera_pin_chip cs47l85_pin_chip;
extern const struct madera_pin_chip cs47l90_pin_chip;
#endif
......@@ -52,6 +52,26 @@ config CHROMEOS_TBMC
config CROS_EC_CTL
tristate
config CROS_EC_I2C
tristate "ChromeOS Embedded Controller (I2C)"
depends on MFD_CROS_EC && I2C
help
If you say Y here, you get support for talking to the ChromeOS
EC through an I2C bus. This uses a simple byte-level protocol with
a checksum. Failing accesses will be retried three times to
improve reliability.
config CROS_EC_SPI
tristate "ChromeOS Embedded Controller (SPI)"
depends on MFD_CROS_EC && SPI
---help---
If you say Y here, you get support for talking to the ChromeOS EC
through a SPI bus, using a byte-level protocol. Since the EC's
response time cannot be guaranteed, we support ignoring
'pre-amble' bytes before the response actually starts.
config CROS_EC_LPC
tristate "ChromeOS Embedded Controller (LPC)"
depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
......
......@@ -6,6 +6,8 @@ obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o
cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \
cros_ec_vbc.o cros_ec_debugfs.o
obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o
obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o
cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o
obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o
......
......@@ -506,10 +506,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
}
EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
static int get_next_event_xfer(struct cros_ec_device *ec_dev,
struct cros_ec_command *msg,
int version, uint32_t size)
{
int ret;
msg->version = version;
msg->command = EC_CMD_GET_NEXT_EVENT;
msg->insize = size;
msg->outsize = 0;
ret = cros_ec_cmd_xfer(ec_dev, msg);
if (ret > 0) {
ec_dev->event_size = ret - 1;
memcpy(&ec_dev->event_data, msg->data, ec_dev->event_size);
}
return ret;
}
static int get_next_event(struct cros_ec_device *ec_dev)
{
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
static int cmd_version = 1;
int ret;
if (ec_dev->suspended) {
......@@ -517,18 +538,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
msg->version = 0;
msg->command = EC_CMD_GET_NEXT_EVENT;
msg->insize = sizeof(ec_dev->event_data);
msg->outsize = 0;
if (cmd_version == 1) {
ret = get_next_event_xfer(ec_dev, msg, cmd_version,
sizeof(struct ec_response_get_next_event_v1));
if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
return ret;
ret = cros_ec_cmd_xfer(ec_dev, msg);
if (ret > 0) {
ec_dev->event_size = ret - 1;
memcpy(&ec_dev->event_data, msg->data,
sizeof(ec_dev->event_data));
/* Fallback to version 0 for future send attempts */
cmd_version = 0;
}
ret = get_next_event_xfer(ec_dev, msg, cmd_version,
sizeof(struct ec_response_get_next_event));
return ret;
}
......
......@@ -98,7 +98,7 @@ struct da9063_regulator_info {
struct da9063_dev_model {
const struct da9063_regulator_info *regulator_info;
unsigned n_regulators;
unsigned dev_model;
enum da9063_type type;
};
/* Single regulator settings */
......@@ -529,6 +529,32 @@ static const struct da9063_regulator_info da9063_regulator_info[] = {
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A,
DA9063_BMEM_ILIM_MASK),
},
{
DA9063_LDO(DA9063, LDO3, 900, 20, 3440),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO3_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO3_LIM),
},
{
DA9063_LDO(DA9063, LDO7, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO7_CONT, DA9063_VLDO7_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO7_LIM),
},
{
DA9063_LDO(DA9063, LDO8, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO8_CONT, DA9063_VLDO8_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO8_LIM),
},
{
DA9063_LDO(DA9063, LDO9, 950, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO9_CONT, DA9063_VLDO9_SEL),
},
{
DA9063_LDO(DA9063, LDO11, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO11_CONT, DA9063_VLDO11_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO11_LIM),
},
/* The following LDOs are present only on DA9063, not on DA9063L */
{
DA9063_LDO(DA9063, LDO1, 600, 20, 1860),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO1_SEL),
......@@ -537,11 +563,6 @@ static const struct da9063_regulator_info da9063_regulator_info[] = {
DA9063_LDO(DA9063, LDO2, 600, 20, 1860),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO2_SEL),
},
{
DA9063_LDO(DA9063, LDO3, 900, 20, 3440),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO3_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO3_LIM),
},
{
DA9063_LDO(DA9063, LDO4, 900, 20, 3440),
.suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VLDO4_SEL),
......@@ -555,29 +576,11 @@ static const struct da9063_regulator_info da9063_regulator_info[] = {
DA9063_LDO(DA9063, LDO6, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO6_CONT, DA9063_VLDO6_SEL),
},
{
DA9063_LDO(DA9063, LDO7, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO7_CONT, DA9063_VLDO7_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO7_LIM),
},
{
DA9063_LDO(DA9063, LDO8, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO8_CONT, DA9063_VLDO8_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO8_LIM),
},
{
DA9063_LDO(DA9063, LDO9, 950, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO9_CONT, DA9063_VLDO9_SEL),
},
{
DA9063_LDO(DA9063, LDO10, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO10_CONT, DA9063_VLDO10_SEL),
},
{
DA9063_LDO(DA9063, LDO11, 900, 50, 3600),
.suspend = BFIELD(DA9063_REG_LDO11_CONT, DA9063_VLDO11_SEL),
.oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO11_LIM),
},
};
/* Link chip model with regulators info table */
......@@ -585,7 +588,12 @@ static struct da9063_dev_model regulators_models[] = {
{
.regulator_info = da9063_regulator_info,
.n_regulators = ARRAY_SIZE(da9063_regulator_info),
.dev_model = PMIC_DA9063,
.type = PMIC_TYPE_DA9063,
},
{
.regulator_info = da9063_regulator_info,
.n_regulators = ARRAY_SIZE(da9063_regulator_info) - 6,
.type = PMIC_TYPE_DA9063L,
},
{ }
};
......@@ -641,28 +649,34 @@ static struct of_regulator_match da9063_matches[] = {
[DA9063_ID_BPERI] = { .name = "bperi", },
[DA9063_ID_BCORES_MERGED] = { .name = "bcores-merged" },
[DA9063_ID_BMEM_BIO_MERGED] = { .name = "bmem-bio-merged", },
[DA9063_ID_LDO3] = { .name = "ldo3", },
[DA9063_ID_LDO7] = { .name = "ldo7", },
[DA9063_ID_LDO8] = { .name = "ldo8", },
[DA9063_ID_LDO9] = { .name = "ldo9", },
[DA9063_ID_LDO11] = { .name = "ldo11", },
/* The following LDOs are present only on DA9063, not on DA9063L */
[DA9063_ID_LDO1] = { .name = "ldo1", },
[DA9063_ID_LDO2] = { .name = "ldo2", },
[DA9063_ID_LDO3] = { .name = "ldo3", },
[DA9063_ID_LDO4] = { .name = "ldo4", },
[DA9063_ID_LDO5] = { .name = "ldo5", },
[DA9063_ID_LDO6] = { .name = "ldo6", },
[DA9063_ID_LDO7] = { .name = "ldo7", },
[DA9063_ID_LDO8] = { .name = "ldo8", },
[DA9063_ID_LDO9] = { .name = "ldo9", },
[DA9063_ID_LDO10] = { .name = "ldo10", },
[DA9063_ID_LDO11] = { .name = "ldo11", },
};
static struct da9063_regulators_pdata *da9063_parse_regulators_dt(
struct platform_device *pdev,
struct of_regulator_match **da9063_reg_matches)
{
struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
struct da9063_regulators_pdata *pdata;
struct da9063_regulator_data *rdata;
struct device_node *node;
int da9063_matches_len = ARRAY_SIZE(da9063_matches);
int i, n, num;
if (da9063->type == PMIC_TYPE_DA9063L)
da9063_matches_len -= 6;
node = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
if (!node) {
dev_err(&pdev->dev, "Regulators device node not found\n");
......@@ -670,7 +684,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt(
}
num = of_regulator_match(&pdev->dev, node, da9063_matches,
ARRAY_SIZE(da9063_matches));
da9063_matches_len);
of_node_put(node);
if (num < 0) {
dev_err(&pdev->dev, "Failed to match regulators\n");
......@@ -689,7 +703,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt(
pdata->n_regulators = num;
n = 0;
for (i = 0; i < ARRAY_SIZE(da9063_matches); i++) {
for (i = 0; i < da9063_matches_len; i++) {
if (!da9063_matches[i].init_data)
continue;
......@@ -741,12 +755,12 @@ static int da9063_regulator_probe(struct platform_device *pdev)
/* Find regulators set for particular device model */
for (model = regulators_models; model->regulator_info; model++) {
if (model->dev_model == da9063->model)
if (model->type == da9063->type)
break;
}
if (!model->regulator_info) {
dev_err(&pdev->dev, "Chip model not recognised (%u)\n",
da9063->model);
da9063->type);
return -ENODEV;
}
......
......@@ -296,6 +296,8 @@
#define AS3722_ADC1_CONV_NOTREADY BIT(7)
#define AS3722_ADC1_SOURCE_SELECT_MASK 0x1F
#define AS3722_CTRL_SEQU1_AC_OK_PWR_ON BIT(0)
/* GPIO modes */
#define AS3722_GPIO_MODE_MASK 0x07
#define AS3722_GPIO_MODE_INPUT 0x00
......@@ -391,6 +393,7 @@ struct as3722 {
unsigned long irq_flags;
bool en_intern_int_pullup;
bool en_intern_i2c_pullup;
bool en_ac_ok_pwr_on;
struct regmap_irq_chip_data *irq_data;
};
......
......@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
struct ec_response_get_next_event event_data;
struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
};
......
......@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
/* EC supports CEC commands */
EC_FEATURE_CEC = 35,
};
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
......@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
/* Notify the AP that something happened on CEC */
EC_MKBP_EVENT_CEC_EVENT = 8,
/* Send an incoming CEC message to the AP */
EC_MKBP_EVENT_CEC_MESSAGE = 9,
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
};
......@@ -2093,12 +2101,28 @@ union ec_response_get_next_data {
uint32_t sysrq;
} __packed;
union ec_response_get_next_data_v1 {
uint8_t key_matrix[16];
uint32_t host_event;
uint32_t buttons;
uint32_t switches;
uint32_t sysrq;
uint32_t cec_events;
uint8_t cec_message[16];
} __packed;
struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
} __packed;
struct ec_response_get_next_event_v1 {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data_v1 data;
} __packed;
/* Bit indices for buttons and switches.*/
/* Buttons */
#define EC_MKBP_POWER_BUTTON 0
......@@ -2593,14 +2617,18 @@ struct ec_params_current_limit {
} __packed;
/*
* Set maximum external power current.
* Set maximum external voltage / current.
*/
#define EC_CMD_EXT_POWER_CURRENT_LIMIT 0xa2
#define EC_CMD_EXTERNAL_POWER_LIMIT 0x00A2
struct ec_params_ext_power_current_limit {
uint32_t limit; /* in mA */
/* Command v0 is used only on Spring and is obsolete + unsupported */
struct ec_params_external_power_limit_v1 {
uint16_t current_lim; /* in mA, or EC_POWER_LIMIT_NONE to clear limit */
uint16_t voltage_lim; /* in mV, or EC_POWER_LIMIT_NONE to clear limit */
} __packed;
#define EC_POWER_LIMIT_NONE 0xffff
/* Inform the EC when entering a sleep state */
#define EC_CMD_HOST_SLEEP_EVENT 0xa9
......@@ -2829,6 +2857,79 @@ struct ec_params_reboot_ec {
#define EC_ACPI_MEM_VERSION_CURRENT 1
/*****************************************************************************/
/*
* HDMI CEC commands
*
* These commands are for sending and receiving message via HDMI CEC
*/
#define EC_MAX_CEC_MSG_LEN 16
/* CEC message from the AP to be written on the CEC bus */
#define EC_CMD_CEC_WRITE_MSG 0x00B8
/**
* struct ec_params_cec_write - Message to write to the CEC bus
* @msg: message content to write to the CEC bus
*/
struct ec_params_cec_write {
uint8_t msg[EC_MAX_CEC_MSG_LEN];
} __packed;
/* Set various CEC parameters */
#define EC_CMD_CEC_SET 0x00BA
/**
* struct ec_params_cec_set - CEC parameters set
* @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
* @val: in case cmd is CEC_CMD_ENABLE, this field can be 0 to disable CEC
* or 1 to enable CEC functionality, in case cmd is CEC_CMD_LOGICAL_ADDRESS,
* this field encodes the requested logical address between 0 and 15
* or 0xff to unregister
*/
struct ec_params_cec_set {
uint8_t cmd; /* enum cec_command */
uint8_t val;
} __packed;
/* Read various CEC parameters */
#define EC_CMD_CEC_GET 0x00BB
/**
* struct ec_params_cec_get - CEC parameters get
* @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
*/
struct ec_params_cec_get {
uint8_t cmd; /* enum cec_command */
} __packed;
/**
* struct ec_response_cec_get - CEC parameters get response
* @val: in case cmd was CEC_CMD_ENABLE, this field will 0 if CEC is
* disabled or 1 if CEC functionality is enabled,
* in case cmd was CEC_CMD_LOGICAL_ADDRESS, this will encode the
* configured logical address between 0 and 15 or 0xff if unregistered
*/
struct ec_response_cec_get {
uint8_t val;
} __packed;
/* CEC parameters command */
enum ec_cec_command {
/* CEC reading, writing and events enable */
CEC_CMD_ENABLE,
/* CEC logical address */
CEC_CMD_LOGICAL_ADDRESS,
};
/* Events from CEC to AP */
enum mkbp_cec_event {
/* Outgoing message was acknowledged by a follower */
EC_MKBP_CEC_SEND_OK = BIT(0),
/* Outgoing message was not acknowledged */
EC_MKBP_CEC_SEND_FAILED = BIT(1),
};
/*****************************************************************************/
/*
* Special commands
......@@ -2974,6 +3075,12 @@ enum usb_chg_type {
USB_CHG_TYPE_VBUS,
USB_CHG_TYPE_UNKNOWN,
};
enum usb_power_roles {
USB_PD_PORT_POWER_DISCONNECTED,
USB_PD_PORT_POWER_SOURCE,
USB_PD_PORT_POWER_SINK,
USB_PD_PORT_POWER_SINK_NOT_CHARGING,
};
struct usb_chg_measures {
uint16_t voltage_max;
......@@ -2991,6 +3098,120 @@ struct ec_response_usb_pd_power_info {
uint32_t max_power;
} __packed;
struct ec_params_usb_pd_info_request {
uint8_t port;
} __packed;
/* Read USB-PD Device discovery info */
#define EC_CMD_USB_PD_DISCOVERY 0x0113
struct ec_params_usb_pd_discovery_entry {
uint16_t vid; /* USB-IF VID */
uint16_t pid; /* USB-IF PID */
uint8_t ptype; /* product type (hub,periph,cable,ama) */
} __packed;
/* Override default charge behavior */
#define EC_CMD_PD_CHARGE_PORT_OVERRIDE 0x0114
/* Negative port parameters have special meaning */
enum usb_pd_override_ports {
OVERRIDE_DONT_CHARGE = -2,
OVERRIDE_OFF = -1,
/* [0, CONFIG_USB_PD_PORT_COUNT): Port# */
};
struct ec_params_charge_port_override {
int16_t override_port; /* Override port# */
} __packed;
/* Read (and delete) one entry of PD event log */
#define EC_CMD_PD_GET_LOG_ENTRY 0x0115
struct ec_response_pd_log {
uint32_t timestamp; /* relative timestamp in milliseconds */
uint8_t type; /* event type : see PD_EVENT_xx below */
uint8_t size_port; /* [7:5] port number [4:0] payload size in bytes */
uint16_t data; /* type-defined data payload */
uint8_t payload[0]; /* optional additional data payload: 0..16 bytes */
} __packed;
/* The timestamp is the microsecond counter shifted to get about a ms. */
#define PD_LOG_TIMESTAMP_SHIFT 10 /* 1 LSB = 1024us */
#define PD_LOG_SIZE_MASK 0x1f
#define PD_LOG_PORT_MASK 0xe0
#define PD_LOG_PORT_SHIFT 5
#define PD_LOG_PORT_SIZE(port, size) (((port) << PD_LOG_PORT_SHIFT) | \
((size) & PD_LOG_SIZE_MASK))
#define PD_LOG_PORT(size_port) ((size_port) >> PD_LOG_PORT_SHIFT)
#define PD_LOG_SIZE(size_port) ((size_port) & PD_LOG_SIZE_MASK)
/* PD event log : entry types */
/* PD MCU events */
#define PD_EVENT_MCU_BASE 0x00
#define PD_EVENT_MCU_CHARGE (PD_EVENT_MCU_BASE+0)
#define PD_EVENT_MCU_CONNECT (PD_EVENT_MCU_BASE+1)
/* Reserved for custom board event */
#define PD_EVENT_MCU_BOARD_CUSTOM (PD_EVENT_MCU_BASE+2)
/* PD generic accessory events */
#define PD_EVENT_ACC_BASE 0x20
#define PD_EVENT_ACC_RW_FAIL (PD_EVENT_ACC_BASE+0)
#define PD_EVENT_ACC_RW_ERASE (PD_EVENT_ACC_BASE+1)
/* PD power supply events */
#define PD_EVENT_PS_BASE 0x40
#define PD_EVENT_PS_FAULT (PD_EVENT_PS_BASE+0)
/* PD video dongles events */
#define PD_EVENT_VIDEO_BASE 0x60
#define PD_EVENT_VIDEO_DP_MODE (PD_EVENT_VIDEO_BASE+0)
#define PD_EVENT_VIDEO_CODEC (PD_EVENT_VIDEO_BASE+1)
/* Returned in the "type" field, when there is no entry available */
#define PD_EVENT_NO_ENTRY 0xff
/*
* PD_EVENT_MCU_CHARGE event definition :
* the payload is "struct usb_chg_measures"
* the data field contains the port state flags as defined below :
*/
/* Port partner is a dual role device */
#define CHARGE_FLAGS_DUAL_ROLE BIT(15)
/* Port is the pending override port */
#define CHARGE_FLAGS_DELAYED_OVERRIDE BIT(14)
/* Port is the override port */
#define CHARGE_FLAGS_OVERRIDE BIT(13)
/* Charger type */
#define CHARGE_FLAGS_TYPE_SHIFT 3
#define CHARGE_FLAGS_TYPE_MASK (0xf << CHARGE_FLAGS_TYPE_SHIFT)
/* Power delivery role */
#define CHARGE_FLAGS_ROLE_MASK (7 << 0)
/*
* PD_EVENT_PS_FAULT data field flags definition :
*/
#define PS_FAULT_OCP 1
#define PS_FAULT_FAST_OCP 2
#define PS_FAULT_OVP 3
#define PS_FAULT_DISCH 4
/*
* PD_EVENT_VIDEO_CODEC payload is "struct mcdp_info".
*/
struct mcdp_version {
uint8_t major;
uint8_t minor;
uint16_t build;
} __packed;
struct mcdp_info {
uint8_t family[2];
uint8_t chipid[2];
struct mcdp_version irom;
struct mcdp_version fw;
} __packed;
/* struct mcdp_info field decoding */
#define MCDP_CHIPID(chipid) ((chipid[0] << 8) | chipid[1])
#define MCDP_FAMILY(family) ((family[0] << 8) | family[1])
/* Get info about USB-C SS muxes */
#define EC_CMD_USB_PD_MUX_INFO 0x11a
......
......@@ -29,8 +29,11 @@
#define DA9063_DRVNAME_RTC "da9063-rtc"
#define DA9063_DRVNAME_VIBRATION "da9063-vibration"
enum da9063_models {
PMIC_DA9063 = 0x61,
#define PMIC_CHIP_ID_DA9063 0x61
enum da9063_type {
PMIC_TYPE_DA9063 = 0,
PMIC_TYPE_DA9063L,
};
enum da9063_variant_codes {
......@@ -72,13 +75,10 @@ enum da9063_irqs {
DA9063_IRQ_GPI15,
};
#define DA9063_IRQ_BASE_OFFSET 0
#define DA9063_NUM_IRQ (DA9063_IRQ_GPI15 + 1 - DA9063_IRQ_BASE_OFFSET)
struct da9063 {
/* Device */
struct device *dev;
unsigned short model;
enum da9063_type type;
unsigned char variant_code;
unsigned int flags;
......@@ -94,7 +94,4 @@ struct da9063 {
int da9063_device_init(struct da9063 *da9063, unsigned int irq);
int da9063_irq_init(struct da9063 *da9063);
void da9063_device_exit(struct da9063 *da9063);
void da9063_irq_exit(struct da9063 *da9063);
#endif /* __MFD_DA9063_CORE_H__ */
// SPDX-License-Identifier: GPL-2.0
/*
* MFD internals for Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#ifndef MADERA_CORE_H
#define MADERA_CORE_H
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/mfd/madera/pdata.h>
#include <linux/notifier.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
enum madera_type {
/* 0 is reserved for indicating failure to identify */
CS47L35 = 1,
CS47L85 = 2,
CS47L90 = 3,
CS47L91 = 4,
WM1840 = 7,
};
#define MADERA_MAX_CORE_SUPPLIES 2
#define MADERA_MAX_GPIOS 40
#define CS47L35_NUM_GPIOS 16
#define CS47L85_NUM_GPIOS 40
#define CS47L90_NUM_GPIOS 38
#define MADERA_MAX_MICBIAS 4
/* Notifier events */
#define MADERA_NOTIFY_VOICE_TRIGGER 0x1
#define MADERA_NOTIFY_HPDET 0x2
#define MADERA_NOTIFY_MICDET 0x4
/* GPIO Function Definitions */
#define MADERA_GP_FN_ALTERNATE 0x00
#define MADERA_GP_FN_GPIO 0x01
#define MADERA_GP_FN_DSP_GPIO 0x02
#define MADERA_GP_FN_IRQ1 0x03
#define MADERA_GP_FN_IRQ2 0x04
#define MADERA_GP_FN_FLL1_CLOCK 0x10
#define MADERA_GP_FN_FLL2_CLOCK 0x11
#define MADERA_GP_FN_FLL3_CLOCK 0x12
#define MADERA_GP_FN_FLLAO_CLOCK 0x13
#define MADERA_GP_FN_FLL1_LOCK 0x18
#define MADERA_GP_FN_FLL2_LOCK 0x19
#define MADERA_GP_FN_FLL3_LOCK 0x1A
#define MADERA_GP_FN_FLLAO_LOCK 0x1B
#define MADERA_GP_FN_OPCLK_OUT 0x40
#define MADERA_GP_FN_OPCLK_ASYNC_OUT 0x41
#define MADERA_GP_FN_PWM1 0x48
#define MADERA_GP_FN_PWM2 0x49
#define MADERA_GP_FN_SPDIF_OUT 0x4C
#define MADERA_GP_FN_HEADPHONE_DET 0x50
#define MADERA_GP_FN_MIC_DET 0x58
#define MADERA_GP_FN_DRC1_SIGNAL_DETECT 0x80
#define MADERA_GP_FN_DRC2_SIGNAL_DETECT 0x81
#define MADERA_GP_FN_ASRC1_IN1_LOCK 0x88
#define MADERA_GP_FN_ASRC1_IN2_LOCK 0x89
#define MADERA_GP_FN_ASRC2_IN1_LOCK 0x8A
#define MADERA_GP_FN_ASRC2_IN2_LOCK 0x8B
#define MADERA_GP_FN_DSP_IRQ1 0xA0
#define MADERA_GP_FN_DSP_IRQ2 0xA1
#define MADERA_GP_FN_DSP_IRQ3 0xA2
#define MADERA_GP_FN_DSP_IRQ4 0xA3
#define MADERA_GP_FN_DSP_IRQ5 0xA4
#define MADERA_GP_FN_DSP_IRQ6 0xA5
#define MADERA_GP_FN_DSP_IRQ7 0xA6
#define MADERA_GP_FN_DSP_IRQ8 0xA7
#define MADERA_GP_FN_DSP_IRQ9 0xA8
#define MADERA_GP_FN_DSP_IRQ10 0xA9
#define MADERA_GP_FN_DSP_IRQ11 0xAA
#define MADERA_GP_FN_DSP_IRQ12 0xAB
#define MADERA_GP_FN_DSP_IRQ13 0xAC
#define MADERA_GP_FN_DSP_IRQ14 0xAD
#define MADERA_GP_FN_DSP_IRQ15 0xAE
#define MADERA_GP_FN_DSP_IRQ16 0xAF
#define MADERA_GP_FN_HPOUT1L_SC 0xB0
#define MADERA_GP_FN_HPOUT1R_SC 0xB1
#define MADERA_GP_FN_HPOUT2L_SC 0xB2
#define MADERA_GP_FN_HPOUT2R_SC 0xB3
#define MADERA_GP_FN_HPOUT3L_SC 0xB4
#define MADERA_GP_FN_HPOUT4R_SC 0xB5
#define MADERA_GP_FN_SPKOUTL_SC 0xB6
#define MADERA_GP_FN_SPKOUTR_SC 0xB7
#define MADERA_GP_FN_HPOUT1L_ENA 0xC0
#define MADERA_GP_FN_HPOUT1R_ENA 0xC1
#define MADERA_GP_FN_HPOUT2L_ENA 0xC2
#define MADERA_GP_FN_HPOUT2R_ENA 0xC3
#define MADERA_GP_FN_HPOUT3L_ENA 0xC4
#define MADERA_GP_FN_HPOUT4R_ENA 0xC5
#define MADERA_GP_FN_SPKOUTL_ENA 0xC6
#define MADERA_GP_FN_SPKOUTR_ENA 0xC7
#define MADERA_GP_FN_HPOUT1L_DIS 0xD0
#define MADERA_GP_FN_HPOUT1R_DIS 0xD1
#define MADERA_GP_FN_HPOUT2L_DIS 0xD2
#define MADERA_GP_FN_HPOUT2R_DIS 0xD3
#define MADERA_GP_FN_HPOUT3L_DIS 0xD4
#define MADERA_GP_FN_HPOUT4R_DIS 0xD5
#define MADERA_GP_FN_SPKOUTL_DIS 0xD6
#define MADERA_GP_FN_SPKOUTR_DIS 0xD7
#define MADERA_GP_FN_SPK_SHUTDOWN 0xE0
#define MADERA_GP_FN_SPK_OVH_SHUTDOWN 0xE1
#define MADERA_GP_FN_SPK_OVH_WARN 0xE2
#define MADERA_GP_FN_TIMER1_STATUS 0x140
#define MADERA_GP_FN_TIMER2_STATUS 0x141
#define MADERA_GP_FN_TIMER3_STATUS 0x142
#define MADERA_GP_FN_TIMER4_STATUS 0x143
#define MADERA_GP_FN_TIMER5_STATUS 0x144
#define MADERA_GP_FN_TIMER6_STATUS 0x145
#define MADERA_GP_FN_TIMER7_STATUS 0x146
#define MADERA_GP_FN_TIMER8_STATUS 0x147
#define MADERA_GP_FN_EVENTLOG1_FIFO_STS 0x150
#define MADERA_GP_FN_EVENTLOG2_FIFO_STS 0x151
#define MADERA_GP_FN_EVENTLOG3_FIFO_STS 0x152
#define MADERA_GP_FN_EVENTLOG4_FIFO_STS 0x153
#define MADERA_GP_FN_EVENTLOG5_FIFO_STS 0x154
#define MADERA_GP_FN_EVENTLOG6_FIFO_STS 0x155
#define MADERA_GP_FN_EVENTLOG7_FIFO_STS 0x156
#define MADERA_GP_FN_EVENTLOG8_FIFO_STS 0x157
struct snd_soc_dapm_context;
/*
* struct madera - internal data shared by the set of Madera drivers
*
* This should not be used by anything except child drivers of the Madera MFD
*
* @regmap: pointer to the regmap instance for 16-bit registers
* @regmap_32bit: pointer to the regmap instance for 32-bit registers
* @dev: pointer to the MFD device
* @type: type of codec
* @rev: silicon revision
* @type_name: display name of this codec
* @num_core_supplies: number of core supply regulators
* @core_supplies: list of core supplies that are always required
* @dcvdd: pointer to DCVDD regulator
* @internal_dcvdd: true if DCVDD is supplied from the internal LDO1
* @pdata: our pdata
* @irq_dev: the irqchip child driver device
* @irq: host irq number from SPI or I2C configuration
* @out_clamp: indicates output clamp state for each analogue output
* @out_shorted: indicates short circuit state for each analogue output
* @hp_ena: bitflags of enable state for the headphone outputs
* @num_micbias: number of MICBIAS outputs
* @num_childbias: number of child biases for each MICBIAS
* @dapm: pointer to codec driver DAPM context
* @notifier: notifier for signalling events to ASoC machine driver
*/
struct madera {
struct regmap *regmap;
struct regmap *regmap_32bit;
struct device *dev;
enum madera_type type;
unsigned int rev;
const char *type_name;
int num_core_supplies;
struct regulator_bulk_data core_supplies[MADERA_MAX_CORE_SUPPLIES];
struct regulator *dcvdd;
bool internal_dcvdd;
struct madera_pdata pdata;
struct device *irq_dev;
int irq;
unsigned int num_micbias;
unsigned int num_childbias[MADERA_MAX_MICBIAS];
struct snd_soc_dapm_context *dapm;
struct blocking_notifier_head notifier;
};
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* Platform data for Cirrus Logic Madera codecs
*
* Copyright (C) 2015-2018 Cirrus Logic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2.
*/
#ifndef MADERA_PDATA_H
#define MADERA_PDATA_H
#include <linux/kernel.h>
#include <linux/regulator/arizona-ldo1.h>
#include <linux/regulator/arizona-micsupp.h>
#include <linux/regulator/machine.h>
#define MADERA_MAX_MICBIAS 4
#define MADERA_MAX_CHILD_MICBIAS 4
#define MADERA_MAX_GPSW 2
struct gpio_desc;
struct pinctrl_map;
struct madera_irqchip_pdata;
struct madera_codec_pdata;
/**
* struct madera_pdata - Configuration data for Madera devices
*
* @reset: GPIO controlling /RESET (NULL = none)
* @ldo1: Substruct of pdata for the LDO1 regulator
* @micvdd: Substruct of pdata for the MICVDD regulator
* @irq_flags: Mode for primary IRQ (defaults to active low)
* @gpio_base: Base GPIO number
* @gpio_configs: Array of GPIO configurations (See Documentation/pinctrl.txt)
* @n_gpio_configs: Number of entries in gpio_configs
* @gpsw: General purpose switch mode setting. Depends on the external
* hardware connected to the switch. (See the SW1_MODE field
* in the datasheet for the available values for your codec)
*/
struct madera_pdata {
struct gpio_desc *reset;
struct arizona_ldo1_pdata ldo1;
struct arizona_micsupp_pdata micvdd;
unsigned int irq_flags;
int gpio_base;
const struct pinctrl_map *gpio_configs;
int n_gpio_configs;
u32 gpsw[MADERA_MAX_GPSW];
};
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -21,6 +21,7 @@ enum rave_sp_command {
RAVE_SP_CMD_STATUS = 0xA0,
RAVE_SP_CMD_SW_WDT = 0xA1,
RAVE_SP_CMD_PET_WDT = 0xA2,
RAVE_SP_CMD_RMB_EEPROM = 0xA4,
RAVE_SP_CMD_SET_BACKLIGHT = 0xA6,
RAVE_SP_CMD_RESET = 0xA7,
RAVE_SP_CMD_RESET_REASON = 0xA8,
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (C) 2018 ROHM Semiconductors */
#ifndef __LINUX_MFD_BD71837_H__
#define __LINUX_MFD_BD71837_H__
#include <linux/regmap.h>
enum {
BD71837_BUCK1 = 0,
BD71837_BUCK2,
BD71837_BUCK3,
BD71837_BUCK4,
BD71837_BUCK5,
BD71837_BUCK6,
BD71837_BUCK7,
BD71837_BUCK8,
BD71837_LDO1,
BD71837_LDO2,
BD71837_LDO3,
BD71837_LDO4,
BD71837_LDO5,
BD71837_LDO6,
BD71837_LDO7,
BD71837_REGULATOR_CNT,
};
#define BD71837_BUCK1_VOLTAGE_NUM 0x40
#define BD71837_BUCK2_VOLTAGE_NUM 0x40
#define BD71837_BUCK3_VOLTAGE_NUM 0x40
#define BD71837_BUCK4_VOLTAGE_NUM 0x40
#define BD71837_BUCK5_VOLTAGE_NUM 0x08
#define BD71837_BUCK6_VOLTAGE_NUM 0x04
#define BD71837_BUCK7_VOLTAGE_NUM 0x08
#define BD71837_BUCK8_VOLTAGE_NUM 0x40
#define BD71837_LDO1_VOLTAGE_NUM 0x04
#define BD71837_LDO2_VOLTAGE_NUM 0x02
#define BD71837_LDO3_VOLTAGE_NUM 0x10
#define BD71837_LDO4_VOLTAGE_NUM 0x10
#define BD71837_LDO5_VOLTAGE_NUM 0x10
#define BD71837_LDO6_VOLTAGE_NUM 0x10
#define BD71837_LDO7_VOLTAGE_NUM 0x10
enum {
BD71837_REG_REV = 0x00,
BD71837_REG_SWRESET = 0x01,
BD71837_REG_I2C_DEV = 0x02,
BD71837_REG_PWRCTRL0 = 0x03,
BD71837_REG_PWRCTRL1 = 0x04,
BD71837_REG_BUCK1_CTRL = 0x05,
BD71837_REG_BUCK2_CTRL = 0x06,
BD71837_REG_BUCK3_CTRL = 0x07,
BD71837_REG_BUCK4_CTRL = 0x08,
BD71837_REG_BUCK5_CTRL = 0x09,
BD71837_REG_BUCK6_CTRL = 0x0A,
BD71837_REG_BUCK7_CTRL = 0x0B,
BD71837_REG_BUCK8_CTRL = 0x0C,
BD71837_REG_BUCK1_VOLT_RUN = 0x0D,
BD71837_REG_BUCK1_VOLT_IDLE = 0x0E,
BD71837_REG_BUCK1_VOLT_SUSP = 0x0F,
BD71837_REG_BUCK2_VOLT_RUN = 0x10,
BD71837_REG_BUCK2_VOLT_IDLE = 0x11,
BD71837_REG_BUCK3_VOLT_RUN = 0x12,
BD71837_REG_BUCK4_VOLT_RUN = 0x13,
BD71837_REG_BUCK5_VOLT = 0x14,
BD71837_REG_BUCK6_VOLT = 0x15,
BD71837_REG_BUCK7_VOLT = 0x16,
BD71837_REG_BUCK8_VOLT = 0x17,
BD71837_REG_LDO1_VOLT = 0x18,
BD71837_REG_LDO2_VOLT = 0x19,
BD71837_REG_LDO3_VOLT = 0x1A,
BD71837_REG_LDO4_VOLT = 0x1B,
BD71837_REG_LDO5_VOLT = 0x1C,
BD71837_REG_LDO6_VOLT = 0x1D,
BD71837_REG_LDO7_VOLT = 0x1E,
BD71837_REG_TRANS_COND0 = 0x1F,
BD71837_REG_TRANS_COND1 = 0x20,
BD71837_REG_VRFAULTEN = 0x21,
BD71837_REG_MVRFLTMASK0 = 0x22,
BD71837_REG_MVRFLTMASK1 = 0x23,
BD71837_REG_MVRFLTMASK2 = 0x24,
BD71837_REG_RCVCFG = 0x25,
BD71837_REG_RCVNUM = 0x26,
BD71837_REG_PWRONCONFIG0 = 0x27,
BD71837_REG_PWRONCONFIG1 = 0x28,
BD71837_REG_RESETSRC = 0x29,
BD71837_REG_MIRQ = 0x2A,
BD71837_REG_IRQ = 0x2B,
BD71837_REG_IN_MON = 0x2C,
BD71837_REG_POW_STATE = 0x2D,
BD71837_REG_OUT32K = 0x2E,
BD71837_REG_REGLOCK = 0x2F,
BD71837_REG_OTPVER = 0xFF,
BD71837_MAX_REGISTER = 0x100,
};
#define REGLOCK_PWRSEQ 0x1
#define REGLOCK_VREG 0x10
/* Generic BUCK control masks */
#define BD71837_BUCK_SEL 0x02
#define BD71837_BUCK_EN 0x01
#define BD71837_BUCK_RUN_ON 0x04
/* Generic LDO masks */
#define BD71837_LDO_SEL 0x80
#define BD71837_LDO_EN 0x40
/* BD71837 BUCK ramp rate CTRL reg bits */
#define BUCK_RAMPRATE_MASK 0xC0
#define BUCK_RAMPRATE_10P00MV 0x0
#define BUCK_RAMPRATE_5P00MV 0x1
#define BUCK_RAMPRATE_2P50MV 0x2
#define BUCK_RAMPRATE_1P25MV 0x3
/* BD71837_REG_BUCK1_VOLT_RUN bits */
#define BUCK1_RUN_MASK 0x3F
#define BUCK1_RUN_DEFAULT 0x14
/* BD71837_REG_BUCK1_VOLT_SUSP bits */
#define BUCK1_SUSP_MASK 0x3F
#define BUCK1_SUSP_DEFAULT 0x14
/* BD71837_REG_BUCK1_VOLT_IDLE bits */
#define BUCK1_IDLE_MASK 0x3F
#define BUCK1_IDLE_DEFAULT 0x14
/* BD71837_REG_BUCK2_VOLT_RUN bits */
#define BUCK2_RUN_MASK 0x3F
#define BUCK2_RUN_DEFAULT 0x1E
/* BD71837_REG_BUCK2_VOLT_IDLE bits */
#define BUCK2_IDLE_MASK 0x3F
#define BUCK2_IDLE_DEFAULT 0x14
/* BD71837_REG_BUCK3_VOLT_RUN bits */
#define BUCK3_RUN_MASK 0x3F
#define BUCK3_RUN_DEFAULT 0x1E
/* BD71837_REG_BUCK4_VOLT_RUN bits */
#define BUCK4_RUN_MASK 0x3F
#define BUCK4_RUN_DEFAULT 0x1E
/* BD71837_REG_BUCK5_VOLT bits */
#define BUCK5_MASK 0x07
#define BUCK5_DEFAULT 0x02
/* BD71837_REG_BUCK6_VOLT bits */
#define BUCK6_MASK 0x03
#define BUCK6_DEFAULT 0x03
/* BD71837_REG_BUCK7_VOLT bits */
#define BUCK7_MASK 0x07
#define BUCK7_DEFAULT 0x03
/* BD71837_REG_BUCK8_VOLT bits */
#define BUCK8_MASK 0x3F
#define BUCK8_DEFAULT 0x1E
/* BD71837_REG_IRQ bits */
#define IRQ_SWRST 0x40
#define IRQ_PWRON_S 0x20
#define IRQ_PWRON_L 0x10
#define IRQ_PWRON 0x08
#define IRQ_WDOG 0x04
#define IRQ_ON_REQ 0x02
#define IRQ_STBY_REQ 0x01
/* BD71837_REG_OUT32K bits */
#define BD71837_OUT32K_EN 0x01
/* BD71837 gated clock rate */
#define BD71837_CLK_RATE 32768
/* ROHM BD71837 irqs */
enum {
BD71837_INT_STBY_REQ,
BD71837_INT_ON_REQ,
BD71837_INT_WDOG,
BD71837_INT_PWRBTN,
BD71837_INT_PWRBTN_L,
BD71837_INT_PWRBTN_S,
BD71837_INT_SWRST
};
/* ROHM BD71837 interrupt masks */
#define BD71837_INT_SWRST_MASK 0x40
#define BD71837_INT_PWRBTN_S_MASK 0x20
#define BD71837_INT_PWRBTN_L_MASK 0x10
#define BD71837_INT_PWRBTN_MASK 0x8
#define BD71837_INT_WDOG_MASK 0x4
#define BD71837_INT_ON_REQ_MASK 0x2
#define BD71837_INT_STBY_REQ_MASK 0x1
/* BD71837_REG_LDO1_VOLT bits */
#define LDO1_MASK 0x03
/* BD71837_REG_LDO1_VOLT bits */
#define LDO2_MASK 0x20
/* BD71837_REG_LDO3_VOLT bits */
#define LDO3_MASK 0x0F
/* BD71837_REG_LDO4_VOLT bits */
#define LDO4_MASK 0x0F
/* BD71837_REG_LDO5_VOLT bits */
#define LDO5_MASK 0x0F
/* BD71837_REG_LDO6_VOLT bits */
#define LDO6_MASK 0x0F
/* BD71837_REG_LDO7_VOLT bits */
#define LDO7_MASK 0x0F
/* Register write induced reset settings */
/*
* Even though the bit zero is not SWRESET type we still want to write zero
* to it when changing type. Bit zero is 'SWRESET' trigger bit and if we
* write 1 to it we will trigger the action. So always write 0 to it when
* changning SWRESET action - no matter what we read from it.
*/
#define BD71837_SWRESET_TYPE_MASK 7
#define BD71837_SWRESET_TYPE_DISABLED 0
#define BD71837_SWRESET_TYPE_COLD 4
#define BD71837_SWRESET_TYPE_WARM 6
#define BD71837_SWRESET_RESET_MASK 1
#define BD71837_SWRESET_RESET 1
/* Poweroff state transition conditions */
#define BD718XX_ON_REQ_POWEROFF_MASK 1
#define BD718XX_SWRESET_POWEROFF_MASK 2
#define BD718XX_WDOG_POWEROFF_MASK 4
#define BD718XX_KEY_L_POWEROFF_MASK 8
#define BD718XX_POWOFF_TO_SNVS 0
#define BD718XX_POWOFF_TO_RDY 0xF
#define BD718XX_POWOFF_TIME_MASK 0xF0
enum {
BD718XX_POWOFF_TIME_5MS = 0,
BD718XX_POWOFF_TIME_10MS,
BD718XX_POWOFF_TIME_15MS,
BD718XX_POWOFF_TIME_20MS,
BD718XX_POWOFF_TIME_25MS,
BD718XX_POWOFF_TIME_30MS,
BD718XX_POWOFF_TIME_35MS,
BD718XX_POWOFF_TIME_40MS,
BD718XX_POWOFF_TIME_45MS,
BD718XX_POWOFF_TIME_50MS,
BD718XX_POWOFF_TIME_75MS,
BD718XX_POWOFF_TIME_100MS,
BD718XX_POWOFF_TIME_250MS,
BD718XX_POWOFF_TIME_500MS,
BD718XX_POWOFF_TIME_750MS,
BD718XX_POWOFF_TIME_1500MS
};
/* Poweron sequence state transition conditions */
#define BD718XX_RDY_TO_SNVS_MASK 0xF
#define BD718XX_SNVS_TO_RUN_MASK 0xF0
#define BD718XX_PWR_TRIG_KEY_L 1
#define BD718XX_PWR_TRIG_KEY_S 2
#define BD718XX_PWR_TRIG_PMIC_ON 4
#define BD718XX_PWR_TRIG_VSYS_UVLO 8
#define BD718XX_RDY_TO_SNVS_SIFT 0
#define BD718XX_SNVS_TO_RUN_SIFT 4
#define BD718XX_PWRBTN_PRESS_DURATION_MASK 0xF
/* Timeout value for detecting short press */
enum {
BD718XX_PWRBTN_SHORT_PRESS_10MS = 0,
BD718XX_PWRBTN_SHORT_PRESS_500MS,
BD718XX_PWRBTN_SHORT_PRESS_1000MS,
BD718XX_PWRBTN_SHORT_PRESS_1500MS,
BD718XX_PWRBTN_SHORT_PRESS_2000MS,
BD718XX_PWRBTN_SHORT_PRESS_2500MS,
BD718XX_PWRBTN_SHORT_PRESS_3000MS,
BD718XX_PWRBTN_SHORT_PRESS_3500MS,
BD718XX_PWRBTN_SHORT_PRESS_4000MS,
BD718XX_PWRBTN_SHORT_PRESS_4500MS,
BD718XX_PWRBTN_SHORT_PRESS_5000MS,
BD718XX_PWRBTN_SHORT_PRESS_5500MS,
BD718XX_PWRBTN_SHORT_PRESS_6000MS,
BD718XX_PWRBTN_SHORT_PRESS_6500MS,
BD718XX_PWRBTN_SHORT_PRESS_7000MS,
BD718XX_PWRBTN_SHORT_PRESS_7500MS
};
/* Timeout value for detecting LONG press */
enum {
BD718XX_PWRBTN_LONG_PRESS_10MS = 0,
BD718XX_PWRBTN_LONG_PRESS_1S,
BD718XX_PWRBTN_LONG_PRESS_2S,
BD718XX_PWRBTN_LONG_PRESS_3S,
BD718XX_PWRBTN_LONG_PRESS_4S,
BD718XX_PWRBTN_LONG_PRESS_5S,
BD718XX_PWRBTN_LONG_PRESS_6S,
BD718XX_PWRBTN_LONG_PRESS_7S,
BD718XX_PWRBTN_LONG_PRESS_8S,
BD718XX_PWRBTN_LONG_PRESS_9S,
BD718XX_PWRBTN_LONG_PRESS_10S,
BD718XX_PWRBTN_LONG_PRESS_11S,
BD718XX_PWRBTN_LONG_PRESS_12S,
BD718XX_PWRBTN_LONG_PRESS_13S,
BD718XX_PWRBTN_LONG_PRESS_14S,
BD718XX_PWRBTN_LONG_PRESS_15S
};
struct bd71837_pmic;
struct bd71837_clk;
struct bd71837 {
struct device *dev;
struct regmap *regmap;
unsigned long int id;
int chip_irq;
struct regmap_irq_chip_data *irq_data;
struct bd71837_pmic *pmic;
struct bd71837_clk *clk;
};
#endif /* __LINUX_MFD_BD71837_H__ */
......@@ -222,6 +222,12 @@ struct wm8994_pdata {
*/
bool spkmode_pu;
/*
* CS/ADDR must be pulled internally by the device on this
* system.
*/
bool csnaddr_pd;
/**
* Maximum number of channels clocks will be generated for,
* useful for systems where and I2S bus with multiple data
......
......@@ -20,8 +20,10 @@ struct cec_notifier;
#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
/**
* cec_notifier_get - find or create a new cec_notifier for the given device.
* cec_notifier_get_conn - find or create a new cec_notifier for the given
* device and connector tuple.
* @dev: device that sends the events.
* @conn: the connector name from which the event occurs
*
* If a notifier for device @dev already exists, then increase the refcount
* and return that notifier.
......@@ -31,7 +33,8 @@ struct cec_notifier;
*
* Return NULL if the memory could not be allocated.
*/
struct cec_notifier *cec_notifier_get(struct device *dev);
struct cec_notifier *cec_notifier_get_conn(struct device *dev,
const char *conn);
/**
* cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
......@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
struct cec_notifier *notifier);
#else
static inline struct cec_notifier *cec_notifier_get(struct device *dev)
static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
const char *conn)
{
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
......@@ -120,6 +124,23 @@ static inline void cec_register_cec_notifier(struct cec_adapter *adap,
}
#endif
/**
* cec_notifier_get - find or create a new cec_notifier for the given device.
* @dev: device that sends the events.
*
* If a notifier for device @dev already exists, then increase the refcount
* and return that notifier.
*
* If it doesn't exist, then allocate a new notifier struct and return a
* pointer to that new struct.
*
* Return NULL if the memory could not be allocated.
*/
static inline struct cec_notifier *cec_notifier_get(struct device *dev)
{
return cec_notifier_get_conn(dev, NULL);
}
/**
* cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment