twl6037 (palmas)
tps65913 (palmas)
tps65914 (palmas)
+tps659038
Required properties:
- compatible : Should be from the list
ti,tps65913
ti,tps65914
ti,tps80036
+ ti,tps659038
and also the generic series names
ti,palmas
- interrupt-controller : palmas has its own internal IRQs
--- /dev/null
+
+* Samsung S2MPS11 Voltage and Current Regulator
+
+The Samsung S2MP211 is a multi-function device which includes voltage and
+current regulators, RTC, charger controller and other sub-blocks. It is
+interfaced to the host controller using a I2C interface. Each sub-block is
+addressed by the host system using different I2C slave address.
+
+Required properties:
+- compatible: Should be "samsung,s2mps11-pmic".
+- reg: Specifies the I2C slave address of the pmic block. It should be 0x66.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+ the interrupts from s2mps11 are delivered to.
+- interrupts: Interrupt specifiers for interrupt sources.
+
+Optional nodes:
+- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to
+ register these as clocks with common clock framework instantiate a sub-node
+ named "clocks". It uses the common clock binding documented in :
+ [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+ - #clock-cells: should be 1.
+
+ - The following is the list of clocks generated by the controller. Each clock
+ is assigned an identifier and client nodes use this identifier to specify
+ the clock which they consume.
+ Clock ID
+ ----------------------
+ 32KhzAP 0
+ 32KhzCP 1
+ 32KhzBT 2
+
+- regulators: The regulators of s2mps11 that have to be instantiated should be
+included in a sub-node named 'regulators'. Regulator nodes included in this
+sub-node should be of the format as listed below.
+
+ regulator_name {
+ [standard regulator constraints....];
+ };
+
+ regulator-ramp-delay for BUCKs = [6250/12500/25000(default)/50000] uV/us
+
+ BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explictly
+ regulator-ramp-delay = <0> can be used for them to disable ramp delay.
+ In absence of regulator-ramp-delay property, default ramp delay will be used.
+
+NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
+for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
+Grouping of BUCKs sharing ramp rate setting is as follow : BUCK[1, 6],
+BUCK[3, 4], and BUCK[7, 8, 10]
+
+The regulator constraints inside the regulator nodes use the standard regulator
+bindings which are documented elsewhere.
+
+The following are the names of the regulators that the s2mps11 pmic block
+supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
+as per the datasheet of s2mps11.
+
+ - LDOn
+ - valid values for n are 1 to 28
+ - Example: LDO0, LD01, LDO28
+ - BUCKn
+ - valid values for n are 1 to 9.
+ - Example: BUCK1, BUCK2, BUCK9
+
+Example:
+
+ s2mps11_pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+
+ s2m_osc: clocks{
+ #clock-cells = 1;
+ clock-output-names = "xx", "yy", "zz";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ABB_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDD_ALIVE_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <50000>;
+ };
+ };
+ };
ti,smps-range - OTP has the wrong range set for the hardware so override
0 - low range, 1 - high range.
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+ the system power.
+
Example:
#include <dt-bindings/interrupt-controller/irq.h>
ti,ldo6-vibrator;
+ ti,system-power-controller;
+
regulators {
smps12_reg : smps12 {
regulator-name = "smps12";
/* Realtek PCI-Express Memstick Card Interface driver
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/module.h>
{
int ret;
- rtc_devs[0].platform_data = pdata->rtc;
- rtc_devs[0].pdata_size =
- pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+ if (pdata) {
+ rtc_devs[0].platform_data = pdata->rtc;
+ rtc_devs[0].pdata_size =
+ pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+ }
ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
if (ret) {
{
int ret = 0;
struct pm80x_chip *chip;
- struct pm80x_platform_data *pdata = client->dev.platform_data;
+ struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pm80x_subchip *subchip;
ret = pm80x_init(client);
goto err_device_init;
}
- if (pdata->plat_config)
+ if (pdata && pdata->plat_config)
pdata->plat_config(chip, pdata);
return 0;
{
int ret = 0;
struct pm80x_chip *chip;
- struct pm80x_platform_data *pdata = client->dev.platform_data;
+ struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
ret = pm80x_init(client);
if (ret) {
goto err_805_init;
}
- if (pdata->plat_config)
+ if (pdata && pdata->plat_config)
pdata->plat_config(chip, pdata);
err_805_init:
static int pm860x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct pm860x_platform_data *pdata = client->dev.platform_data;
+ struct pm860x_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
struct pm860x_chip *chip;
int ret;
This driver can be built as a module. If built as a module it will be
called "da9055"
+config MFD_DA9063
+ bool "Dialog Semiconductor DA9063 PMIC Support"
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ depends on I2C=y && GENERIC_HARDIRQS
+ help
+ Say yes here for support for the Dialog Semiconductor DA9063 PMIC.
+ This includes the I2C driver and core APIs.
+ Additional drivers must be enabled in order to use the functionality
+ of the device.
+
config MFD_MC13783
tristate
Support for Wolfson Microelectronics WM5110 low power audio SoC
config MFD_WM8997
- bool "Support Wolfson Microelectronics WM8997"
+ bool "Wolfson Microelectronics WM8997"
depends on MFD_ARIZONA
help
Support for Wolfson Microelectronics WM8997 low power audio SoC
da9055-objs := da9055-core.o da9055-i2c.o
obj-$(CONFIG_MFD_DA9055) += da9055.o
+da9063-objs := da9063-core.o da9063-irq.o da9063-i2c.o
+obj-$(CONFIG_MFD_DA9063) += da9063.o
+
obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
obj-$(CONFIG_MFD_MAX8907) += max8907.o
static int aat2870_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct aat2870_platform_data *pdata = client->dev.platform_data;
+ struct aat2870_platform_data *pdata = dev_get_platdata(&client->dev);
struct aat2870_data *aat2870;
int i, j;
int ret = 0;
{
struct ab3100 *ab3100;
struct ab3100_platform_data *ab3100_plf_data =
- client->dev.platform_data;
+ dev_get_platdata(&client->dev);
int err;
int i;
static struct ab8500_prcmu_ranges *debug_ranges;
-struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
[0x0] = {
.num_ranges = 0,
.range = NULL,
},
};
-struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
[0x0] = {
.num_ranges = 0,
.range = NULL,
},
};
-struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
[AB8500_M_FSM_RANK] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
/* Space for 500 registers. */
#define DUMP_MAX_REGS 700
-struct ab8500_register_dump
+static struct ab8500_register_dump
{
u8 bank;
u8 reg;
*/
dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
GFP_KERNEL);
+ if (!dev_attr[irq_index])
+ return -ENOMEM;
+
event_name[irq_index] = kmalloc(count, GFP_KERNEL);
+ if (!event_name[irq_index])
+ return -ENOMEM;
+
sprintf(event_name[irq_index], "%lu", user_val);
dev_attr[irq_index]->show = show_irq;
dev_attr[irq_index]->store = NULL;
gpadc->cal_data[ADC_INPUT_VBAT].offset);
}
+#ifdef CONFIG_PM_RUNTIME
static int ab8500_gpadc_runtime_suspend(struct device *dev)
{
struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
return ret;
}
+#endif
+#ifdef CONFIG_PM_SLEEP
static int ab8500_gpadc_suspend(struct device *dev)
{
struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
mutex_unlock(&gpadc->ab8500_gpadc_lock);
return ret;
}
+#endif
static int ab8500_gpadc_probe(struct platform_device *pdev)
{
static int adp5520_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct adp5520_platform_data *pdata = client->dev.platform_data;
+ struct adp5520_platform_data *pdata = dev_get_platdata(&client->dev);
struct platform_device *pdev;
struct adp5520_chip *chip;
int ret;
}
}
- regulator_disable(arizona->dcvdd);
regcache_cache_only(arizona->regmap, true);
regcache_mark_dirty(arizona->regmap);
+ regulator_disable(arizona->dcvdd);
return 0;
}
int ret;
if (!client->dev.of_node) {
- pdata = client->dev.platform_data;
+ pdata = dev_get_platdata(&client->dev);
if (!pdata)
dev_dbg(&client->dev, "Platform data not found\n");
} else {
/* Core */
static int __init asic3_probe(struct platform_device *pdev)
{
- struct asic3_platform_data *pdata = pdev->dev.platform_data;
+ struct asic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct asic3 *asic;
struct resource *mem;
unsigned long clksel;
static int da903x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct da903x_platform_data *pdata = client->dev.platform_data;
+ struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);
struct da903x_chip *chip;
unsigned int tmp;
int ret;
int da9052_device_init(struct da9052 *da9052, u8 chip_id)
{
- struct da9052_pdata *pdata = da9052->dev->platform_data;
+ struct da9052_pdata *pdata = dev_get_platdata(da9052->dev);
int ret;
mutex_init(&da9052->auxadc_lock);
int da9055_device_init(struct da9055 *da9055)
{
- struct da9055_pdata *pdata = da9055->dev->platform_data;
+ struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
int ret;
+ uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
if (pdata && pdata->init != NULL)
pdata->init(da9055);
else
da9055->irq_base = pdata->irq_base;
+ ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
+ if (ret < 0)
+ return ret;
+
ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
da9055->irq_base, &da9055_regmap_irq_chip,
}
static struct i2c_device_id da9055_i2c_id[] = {
- {"da9055-pmic", 0},
+ {"da9055", 0},
{ }
};
--- /dev/null
+/*
+ * da9063-core.c: Device access for Dialog DA9063 modules
+ *
+ * Copyright 2012 Dialog Semiconductors Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>,
+ * Michal Hajduk <michal.hajduk@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+#include <linux/mfd/da9063/registers.h>
+
+#include <linux/proc_fs.h>
+#include <linux/kthread.h>
+#include <linux/uaccess.h>
+
+
+static struct resource da9063_regulators_resources[] = {
+ {
+ .name = "LDO_LIM",
+ .start = DA9063_IRQ_LDO_LIM,
+ .end = DA9063_IRQ_LDO_LIM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da9063_rtc_resources[] = {
+ {
+ .name = "ALARM",
+ .start = DA9063_IRQ_ALARM,
+ .end = DA9063_IRQ_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "TICK",
+ .start = DA9063_IRQ_TICK,
+ .end = DA9063_IRQ_TICK,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource da9063_onkey_resources[] = {
+ {
+ .start = DA9063_IRQ_ONKEY,
+ .end = DA9063_IRQ_ONKEY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da9063_hwmon_resources[] = {
+ {
+ .start = DA9063_IRQ_ADC_RDY,
+ .end = DA9063_IRQ_ADC_RDY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct mfd_cell da9063_devs[] = {
+ {
+ .name = DA9063_DRVNAME_REGULATORS,
+ .num_resources = ARRAY_SIZE(da9063_regulators_resources),
+ .resources = da9063_regulators_resources,
+ },
+ {
+ .name = DA9063_DRVNAME_LEDS,
+ },
+ {
+ .name = DA9063_DRVNAME_WATCHDOG,
+ },
+ {
+ .name = DA9063_DRVNAME_HWMON,
+ .num_resources = ARRAY_SIZE(da9063_hwmon_resources),
+ .resources = da9063_hwmon_resources,
+ },
+ {
+ .name = DA9063_DRVNAME_ONKEY,
+ .num_resources = ARRAY_SIZE(da9063_onkey_resources),
+ .resources = da9063_onkey_resources,
+ },
+ {
+ .name = DA9063_DRVNAME_RTC,
+ .num_resources = ARRAY_SIZE(da9063_rtc_resources),
+ .resources = da9063_rtc_resources,
+ },
+ {
+ .name = DA9063_DRVNAME_VIBRATION,
+ },
+};
+
+int da9063_device_init(struct da9063 *da9063, unsigned int irq)
+{
+ struct da9063_pdata *pdata = da9063->dev->platform_data;
+ int model, revision;
+ int ret;
+
+ if (pdata) {
+ da9063->flags = pdata->flags;
+ da9063->irq_base = pdata->irq_base;
+ } else {
+ da9063->flags = 0;
+ da9063->irq_base = 0;
+ }
+ da9063->chip_irq = irq;
+
+ if (pdata && pdata->init != NULL) {
+ ret = pdata->init(da9063);
+ if (ret != 0) {
+ dev_err(da9063->dev,
+ "Platform initialization failed.\n");
+ return ret;
+ }
+ }
+
+ ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model);
+ if (ret < 0) {
+ dev_err(da9063->dev, "Cannot read chip model id.\n");
+ return -EIO;
+ }
+ if (model != PMIC_DA9063) {
+ dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model);
+ return -ENODEV;
+ }
+
+ ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision);
+ if (ret < 0) {
+ dev_err(da9063->dev, "Cannot read chip revision id.\n");
+ return -EIO;
+ }
+ revision >>= DA9063_CHIP_VARIANT_SHIFT;
+ if (revision != 3) {
+ dev_err(da9063->dev, "Unknown chip revision: %d\n", revision);
+ return -ENODEV;
+ }
+
+ da9063->model = model;
+ da9063->revision = revision;
+
+ dev_info(da9063->dev,
+ "Device detected (model-ID: 0x%02X rev-ID: 0x%02X)\n",
+ model, revision);
+
+ ret = da9063_irq_init(da9063);
+ if (ret) {
+ dev_err(da9063->dev, "Cannot initialize interrupts.\n");
+ return ret;
+ }
+
+ 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");
+
+ return ret;
+}
+
+void da9063_device_exit(struct da9063 *da9063)
+{
+ mfd_remove_devices(da9063->dev);
+ da9063_irq_exit(da9063);
+}
+
+MODULE_DESCRIPTION("PMIC driver for Dialog DA9063");
+MODULE_AUTHOR("Krystian Garbaciak <krystian.garbaciak@diasemi.com>, Michal Hajduk <michal.hajduk@diasemi.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+/* da9063-i2c.c: Interrupt support for Dialog DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+#include <linux/mfd/da9063/registers.h>
+
+static const struct regmap_range da9063_readable_ranges[] = {
+ {
+ .range_min = DA9063_REG_PAGE_CON,
+ .range_max = DA9063_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_REG_GP_ID_19,
+ }, {
+ .range_min = DA9063_REG_CHIP_ID,
+ .range_max = DA9063_REG_CHIP_VARIANT,
+ },
+};
+
+static const struct regmap_range da9063_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_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_REG_MON_REG_4,
+ }, {
+ .range_min = DA9063_REG_GP_ID_0,
+ .range_max = DA9063_REG_GP_ID_19,
+ },
+};
+
+static const struct regmap_range da9063_volatile_ranges[] = {
+ {
+ .range_min = DA9063_REG_STATUS_A,
+ .range_max = DA9063_REG_EVENT_D,
+ }, {
+ .range_min = DA9063_REG_CONTROL_F,
+ .range_max = DA9063_REG_CONTROL_F,
+ }, {
+ .range_min = DA9063_REG_ADC_MAN,
+ .range_max = DA9063_REG_ADC_MAN,
+ }, {
+ .range_min = DA9063_REG_ADC_RES_L,
+ .range_max = DA9063_REG_SECOND_D,
+ }, {
+ .range_min = DA9063_REG_MON_REG_5,
+ .range_max = DA9063_REG_MON_REG_6,
+ },
+};
+
+static const struct regmap_access_table da9063_readable_table = {
+ .yes_ranges = da9063_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_readable_ranges),
+};
+
+static const struct regmap_access_table da9063_writeable_table = {
+ .yes_ranges = da9063_writeable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_writeable_ranges),
+};
+
+static const struct regmap_access_table da9063_volatile_table = {
+ .yes_ranges = da9063_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_volatile_ranges),
+};
+
+static const struct regmap_range_cfg da9063_range_cfg[] = {
+ {
+ .range_min = DA9063_REG_PAGE_CON,
+ .range_max = DA9063_REG_CHIP_VARIANT,
+ .selector_reg = DA9063_REG_PAGE_CON,
+ .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT,
+ .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT,
+ .window_start = 0,
+ .window_len = 256,
+ }
+};
+
+static struct regmap_config da9063_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .ranges = da9063_range_cfg,
+ .num_ranges = ARRAY_SIZE(da9063_range_cfg),
+ .max_register = DA9063_REG_CHIP_VARIANT,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .rd_table = &da9063_readable_table,
+ .wr_table = &da9063_writeable_table,
+ .volatile_table = &da9063_volatile_table,
+};
+
+static int da9063_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct da9063 *da9063;
+ int ret;
+
+ da9063 = devm_kzalloc(&i2c->dev, sizeof(struct da9063), GFP_KERNEL);
+ if (da9063 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, da9063);
+ da9063->dev = &i2c->dev;
+ da9063->chip_irq = i2c->irq;
+
+ da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
+ if (IS_ERR(da9063->regmap)) {
+ ret = PTR_ERR(da9063->regmap);
+ dev_err(da9063->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ 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},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, da9063_i2c_id);
+
+static struct i2c_driver da9063_i2c_driver = {
+ .driver = {
+ .name = "da9063",
+ .owner = THIS_MODULE,
+ },
+ .probe = da9063_i2c_probe,
+ .remove = da9063_i2c_remove,
+ .id_table = da9063_i2c_id,
+};
+
+module_i2c_driver(da9063_i2c_driver);
--- /dev/null
+/* da9063-irq.c: Interrupts support for Dialog DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+
+#define DA9063_REG_EVENT_A_OFFSET 0
+#define DA9063_REG_EVENT_B_OFFSET 1
+#define DA9063_REG_EVENT_C_OFFSET 2
+#define DA9063_REG_EVENT_D_OFFSET 3
+#define EVENTS_BUF_LEN 4
+
+static const u8 mask_events_buf[] = { [0 ... (EVENTS_BUF_LEN - 1)] = ~0 };
+
+struct da9063_irq_data {
+ u16 reg;
+ u8 mask;
+};
+
+static 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,
+ },
+ /* 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_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,
+ },
+ /* 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,
+ },
+ /* 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,
+ },
+};
+
+static struct regmap_irq_chip da9063_irq_chip = {
+ .name = "da9063-irq",
+ .irqs = da9063_irqs,
+ .num_irqs = DA9063_NUM_IRQ,
+
+ .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,
+};
+
+int da9063_irq_init(struct da9063 *da9063)
+{
+ int ret;
+
+ if (!da9063->chip_irq) {
+ dev_err(da9063->dev, "No IRQ configured\n");
+ return -EINVAL;
+ }
+
+ ret = regmap_add_irq_chip(da9063->regmap, da9063->chip_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+ da9063->irq_base, &da9063_irq_chip,
+ &da9063->regmap_irq);
+ if (ret) {
+ dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n",
+ da9063->chip_irq, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void da9063_irq_exit(struct da9063 *da9063)
+{
+ regmap_del_irq_chip(da9063->chip_irq, da9063->regmap_irq);
+}
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/regmap.h>
#include <sound/pcm.h>
#include <linux/mfd/davinci_voicecodec.h>
-u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)
-{
- return __raw_readl(davinci_vc->base + reg);
-}
-
-void davinci_vc_write(struct davinci_vc *davinci_vc,
- int reg, u32 val)
-{
- __raw_writel(val, davinci_vc->base + reg);
-}
+static struct regmap_config davinci_vc_regmap = {
+ .reg_bits = 32,
+ .val_bits = 32,
+};
static int __init davinci_vc_probe(struct platform_device *pdev)
{
goto fail;
}
+ davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev,
+ davinci_vc->base,
+ &davinci_vc_regmap);
+ if (IS_ERR(davinci_vc->regmap)) {
+ ret = PTR_ERR(davinci_vc->regmap);
+ goto fail;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!res) {
dev_err(&pdev->dev, "no DMA resource\n");
#define CLK_MGT_ENTRY(_name, _branch, _clk38div)[PRCMU_##_name] = \
{ (PRCM_##_name##_MGT), 0 , _branch, _clk38div}
-struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
+static struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
CLK_MGT_ENTRY(SGACLK, PLL_DIV, false),
CLK_MGT_ENTRY(UARTCLK, PLL_FIX, true),
CLK_MGT_ENTRY(MSP02CLK, PLL_FIX, true),
/**
* prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem
*/
-void prcmu_ac_sleep_req()
+void prcmu_ac_sleep_req(void)
{
u32 val;
}
/* MMC/SD inputs -- right after the last config input */
- if (client->dev.platform_data) {
- void (*mmcsd_setup)(unsigned) = client->dev.platform_data;
+ if (dev_get_platdata(&client->dev)) {
+ void (*mmcsd_setup)(unsigned) = dev_get_platdata(&client->dev);
mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
}
static void pcap_isr_work(struct work_struct *work)
{
struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
- struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
+ struct pcap_platform_data *pdata = dev_get_platdata(&pcap->spi->dev);
u32 msr, isr, int_sel, service;
int irq;
static int ezx_pcap_remove(struct spi_device *spi)
{
struct pcap_chip *pcap = spi_get_drvdata(spi);
- struct pcap_platform_data *pdata = spi->dev.platform_data;
+ struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
int i, adc_irq;
/* remove all registered subdevs */
static int ezx_pcap_probe(struct spi_device *spi)
{
- struct pcap_platform_data *pdata = spi->dev.platform_data;
+ struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
struct pcap_chip *pcap;
int i, adc_irq;
int ret = -ENODEV;
static int __init egpio_probe(struct platform_device *pdev)
{
- struct htc_egpio_platform_data *pdata = pdev->dev.platform_data;
+ struct htc_egpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct resource *res;
struct egpio_info *ei;
struct gpio_chip *chip;
int ret = 0;
/* Get the platform and driver data */
- pdata = dev->platform_data;
+ pdata = dev_get_platdata(dev);
htcpld = platform_get_drvdata(pdev);
chip = &htcpld->chip[chip_index];
plat_chip_data = &pdata->chip[chip_index];
struct i2c_board_info info;
/* Get the platform and driver data */
- pdata = dev->platform_data;
+ pdata = dev_get_platdata(dev);
htcpld = platform_get_drvdata(pdev);
chip = &htcpld->chip[chip_index];
plat_chip_data = &pdata->chip[chip_index];
int ret = 0;
/* Get the platform and driver data */
- pdata = dev->platform_data;
+ pdata = dev_get_platdata(dev);
htcpld = platform_get_drvdata(pdev);
chip = &htcpld->chip[chip_index];
plat_chip_data = &pdata->chip[chip_index];
int i;
/* Get the platform and driver data */
- pdata = dev->platform_data;
+ pdata = dev_get_platdata(dev);
htcpld = platform_get_drvdata(pdev);
/* Setup each chip's output GPIOs */
if (!dev)
return -ENODEV;
- pdata = dev->platform_data;
+ pdata = dev_get_platdata(dev);
if (!pdata) {
dev_warn(dev, "Platform data not found for htcpld core!\n");
return -ENXIO;
static int __init pasic3_probe(struct platform_device *pdev)
{
- struct pasic3_platform_data *pdata = pdev->dev.platform_data;
+ struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct pasic3_data *asic;
struct resource *r;
static int intel_msic_init_devices(struct intel_msic *msic)
{
struct platform_device *pdev = msic->pdev;
- struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
+ struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
int ret, i;
if (pdata->gpio) {
static int intel_msic_probe(struct platform_device *pdev)
{
- struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
+ struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct intel_msic *msic;
struct resource *res;
u8 id0, id1;
*/
void kempld_get_mutex(struct kempld_device_data *pld)
{
- struct kempld_platform_data *pdata = pld->dev->platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
mutex_lock(&pld->lock);
pdata->get_hardware_mutex(pld);
*/
void kempld_release_mutex(struct kempld_device_data *pld)
{
- struct kempld_platform_data *pdata = pld->dev->platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
pdata->release_hardware_mutex(pld);
mutex_unlock(&pld->lock);
*/
static int kempld_get_info(struct kempld_device_data *pld)
{
- struct kempld_platform_data *pdata = pld->dev->platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
return pdata->get_info(pld);
}
*/
static int kempld_register_cells(struct kempld_device_data *pld)
{
- struct kempld_platform_data *pdata = pld->dev->platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
return pdata->register_cells(pld);
}
static int kempld_probe(struct platform_device *pdev)
{
- struct kempld_platform_data *pdata = pdev->dev.platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct kempld_device_data *pld;
struct resource *ioport;
static int kempld_remove(struct platform_device *pdev)
{
struct kempld_device_data *pld = platform_get_drvdata(pdev);
- struct kempld_platform_data *pdata = pld->dev->platform_data;
+ struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
mfd_remove_devices(&pdev->dev);
pdata->release_hardware_mutex(pld);
};
static struct dmi_system_id __initdata kempld_dmi_table[] = {
+ {
+ .ident = "BHL6",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+ DMI_MATCH(DMI_BOARD_NAME, "COMe-bHL6"),
+ },
+ .driver_data = (void *)&kempld_platform_data_generic,
+ .callback = kempld_create_platform_device,
+ },
{
.ident = "CCR2",
.matches = {
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
},
+ {
+ .ident = "UTH6",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+ DMI_MATCH(DMI_BOARD_NAME, "COMe-cTH6"),
+ },
+ .driver_data = (void *)&kempld_platform_data_generic,
+ .callback = kempld_create_platform_device,
+ },
{}
};
MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
static int lm3533_device_als_init(struct lm3533 *lm3533)
{
- struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+ struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
int ret;
if (!pdata->als)
static int lm3533_device_bl_init(struct lm3533 *lm3533)
{
- struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+ struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
int i;
int ret;
static int lm3533_device_led_init(struct lm3533 *lm3533)
{
- struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+ struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
int i;
int ret;
static int lm3533_device_init(struct lm3533 *lm3533)
{
- struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+ struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
int ret;
dev_dbg(lm3533->dev, "%s\n", __func__);
static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp8788 *lp;
- struct lp8788_platform_data *pdata = cl->dev.platform_data;
+ struct lp8788_platform_data *pdata = dev_get_platdata(&cl->dev);
int ret;
lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
LPC_COLETO, /* Coleto Creek */
};
-struct lpc_ich_info lpc_chipset_info[] = {
+static struct lpc_ich_info lpc_chipset_info[] = {
[LPC_ICH] = {
.name = "ICH",
.iTCO_version = 1,
const struct i2c_device_id *id)
{
struct max77686_dev *max77686 = NULL;
- struct max77686_platform_data *pdata = i2c->dev.platform_data;
+ struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev);
unsigned int data;
int ret = 0;
const struct i2c_device_id *id)
{
struct max77693_dev *max77693;
- struct max77693_platform_data *pdata = i2c->dev.platform_data;
+ struct max77693_platform_data *pdata = dev_get_platdata(&i2c->dev);
u8 reg_data;
int ret = 0;
static int max8925_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct max8925_platform_data *pdata = client->dev.platform_data;
+ struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
static struct max8925_chip *chip;
struct device_node *node = client->dev.of_node;
#ifdef CONFIG_OF
static struct of_device_id max8997_pmic_dt_match[] = {
- { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+ { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
{},
};
#endif
const struct i2c_device_id *id)
{
struct max8997_dev *max8997;
- struct max8997_platform_data *pdata = i2c->dev.platform_data;
+ struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev);
int ret = 0;
- max8997 = kzalloc(sizeof(struct max8997_dev), GFP_KERNEL);
+ max8997 = devm_kzalloc(&i2c->dev, sizeof(struct max8997_dev),
+ GFP_KERNEL);
if (max8997 == NULL)
return -ENOMEM;
if (max8997->dev->of_node) {
pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
- if (IS_ERR(pdata)) {
- ret = PTR_ERR(pdata);
- goto err;
- }
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
}
if (!pdata)
- goto err;
+ return ret;
max8997->pdata = pdata;
max8997->ono = pdata->ono;
i2c_unregister_device(max8997->muic);
i2c_unregister_device(max8997->haptic);
i2c_unregister_device(max8997->rtc);
-err:
- kfree(max8997);
return ret;
}
i2c_unregister_device(max8997->muic);
i2c_unregister_device(max8997->haptic);
i2c_unregister_device(max8997->rtc);
- kfree(max8997);
return 0;
}
static int max8998_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct max8998_platform_data *pdata = i2c->dev.platform_data;
+ struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct max8998_dev *max8998;
int ret = 0;
- max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL);
+ max8998 = devm_kzalloc(&i2c->dev, sizeof(struct max8998_dev),
+ GFP_KERNEL);
if (max8998 == NULL)
return -ENOMEM;
mfd_remove_devices(max8998->dev);
max8998_irq_exit(max8998);
i2c_unregister_device(max8998->rtc);
- kfree(max8998);
return ret;
}
mfd_remove_devices(max8998->dev);
max8998_irq_exit(max8998);
i2c_unregister_device(max8998->rtc);
- kfree(max8998);
return 0;
}
static int mcp_sa11x0_probe(struct platform_device *dev)
{
- struct mcp_plat_data *data = dev->dev.platform_data;
+ struct mcp_plat_data *data = dev_get_platdata(&dev->dev);
struct resource *mem0, *mem1;
struct mcp_sa11x0 *m;
struct mcp *mcp;
menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
the_menelaus->mmc_callback = NULL;
- the_menelaus->mmc_callback_data = 0;
+ the_menelaus->mmc_callback_data = NULL;
}
EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
struct i2c_client *c = the_menelaus->client;
mutex_lock(&the_menelaus->lock);
- if (vtg == 0)
+ if (!vtg)
goto set_voltage;
ret = menelaus_read_reg(vtg->vtg_reg);
int rev = 0, val;
int err = 0;
struct menelaus_platform_data *menelaus_pdata =
- client->dev.platform_data;
+ dev_get_platdata(&client->dev);
if (the_menelaus) {
dev_dbg(&client->dev, "only one %s for now\n",
return -ENODEV;
}
- menelaus = kzalloc(sizeof *menelaus, GFP_KERNEL);
+ menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
if (!menelaus)
return -ENOMEM;
rev = menelaus_read_reg(MENELAUS_REV);
if (rev < 0) {
pr_err(DRIVER_NAME ": device not found");
- err = -ENODEV;
- goto fail1;
+ return -ENODEV;
}
/* Ack and disable all Menelaus interrupts */
if (err) {
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
client->irq, err);
- goto fail1;
+ return err;
}
}
val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
if (val < 0)
- goto fail2;
+ goto fail;
if (val & (1 << 7))
menelaus->vcore_hw_mode = 1;
else
if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
err = menelaus_pdata->late_init(&client->dev);
if (err < 0)
- goto fail2;
+ goto fail;
}
menelaus_rtc_init(menelaus);
return 0;
-fail2:
+fail:
free_irq(client->irq, menelaus);
flush_work(&menelaus->work);
-fail1:
- kfree(menelaus);
return err;
}
free_irq(client->irq, menelaus);
flush_work(&menelaus->work);
- kfree(menelaus);
the_menelaus = NULL;
return 0;
}
pdev->dev.parent = parent;
pdev->dev.type = &mfd_dev_type;
+ pdev->dev.dma_mask = parent->dma_mask;
+ pdev->dev.dma_parms = parent->dma_parms;
if (parent->of_node && cell->of_compatible) {
for_each_child_of_node(parent->of_node, np) {
};
/*-------------------------------------------------------------------------*/
-const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
+static const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
static u64 usbhs_dmamask = DMA_BIT_MASK(32);
/*-------------------------------------------------------------------------*/
static int omap_usbhs_alloc_children(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct usbhs_omap_platform_data *pdata = dev->platform_data;
+ struct usbhs_omap_platform_data *pdata = dev_get_platdata(dev);
struct platform_device *ehci;
struct platform_device *ohci;
struct resource *res;
static int usbhs_omap_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct usbhs_omap_platform_data *pdata = dev->platform_data;
+ struct usbhs_omap_platform_data *pdata = dev_get_platdata(dev);
struct usbhs_hcd_omap *omap;
struct resource *res;
int ret = 0;
#include <linux/mfd/palmas.h>
#include <linux/of_device.h>
+#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 | \
+ PALMAS_EXT_CONTROL_ENABLE2 | \
+ PALMAS_EXT_CONTROL_NSLEEP)
+
+struct palmas_sleep_requestor_info {
+ int id;
+ int reg_offset;
+ int bit_pos;
+};
+
+#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \
+ [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \
+ .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \
+ .reg_offset = _offset, \
+ .bit_pos = _pos, \
+ }
+
+static struct palmas_sleep_requestor_info sleep_req_info[] = {
+ EXTERNAL_REQUESTOR(REGEN1, 0, 0),
+ EXTERNAL_REQUESTOR(REGEN2, 0, 1),
+ EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
+ EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
+ EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
+ EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
+ EXTERNAL_REQUESTOR(REGEN3, 0, 6),
+ EXTERNAL_REQUESTOR(SMPS12, 1, 0),
+ EXTERNAL_REQUESTOR(SMPS3, 1, 1),
+ EXTERNAL_REQUESTOR(SMPS45, 1, 2),
+ EXTERNAL_REQUESTOR(SMPS6, 1, 3),
+ EXTERNAL_REQUESTOR(SMPS7, 1, 4),
+ EXTERNAL_REQUESTOR(SMPS8, 1, 5),
+ EXTERNAL_REQUESTOR(SMPS9, 1, 6),
+ EXTERNAL_REQUESTOR(SMPS10, 1, 7),
+ EXTERNAL_REQUESTOR(LDO1, 2, 0),
+ EXTERNAL_REQUESTOR(LDO2, 2, 1),
+ EXTERNAL_REQUESTOR(LDO3, 2, 2),
+ EXTERNAL_REQUESTOR(LDO4, 2, 3),
+ EXTERNAL_REQUESTOR(LDO5, 2, 4),
+ EXTERNAL_REQUESTOR(LDO6, 2, 5),
+ EXTERNAL_REQUESTOR(LDO7, 2, 6),
+ EXTERNAL_REQUESTOR(LDO8, 2, 7),
+ EXTERNAL_REQUESTOR(LDO9, 3, 0),
+ EXTERNAL_REQUESTOR(LDOLN, 3, 1),
+ EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
+};
+
static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
{
.reg_bits = 8,
PALMAS_INT1_MASK),
};
+int palmas_ext_control_req_config(struct palmas *palmas,
+ enum palmas_external_requestor_id id, int ext_ctrl, bool enable)
+{
+ int preq_mask_bit = 0;
+ int reg_add = 0;
+ int bit_pos;
+ int ret;
+
+ if (!(ext_ctrl & PALMAS_EXT_REQ))
+ return 0;
+
+ if (id >= PALMAS_EXTERNAL_REQSTR_ID_MAX)
+ return 0;
+
+ if (ext_ctrl & PALMAS_EXT_CONTROL_NSLEEP) {
+ reg_add = PALMAS_NSLEEP_RES_ASSIGN;
+ preq_mask_bit = 0;
+ } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE1) {
+ reg_add = PALMAS_ENABLE1_RES_ASSIGN;
+ preq_mask_bit = 1;
+ } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE2) {
+ reg_add = PALMAS_ENABLE2_RES_ASSIGN;
+ preq_mask_bit = 2;
+ }
+
+ bit_pos = sleep_req_info[id].bit_pos;
+ reg_add += sleep_req_info[id].reg_offset;
+ if (enable)
+ ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
+ reg_add, BIT(bit_pos), BIT(bit_pos));
+ else
+ ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
+ reg_add, BIT(bit_pos), 0);
+ if (ret < 0) {
+ dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
+ reg_add, ret);
+ return ret;
+ }
+
+ /* Unmask the PREQ */
+ ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
+ PALMAS_POWER_CTRL, BIT(preq_mask_bit), 0);
+ if (ret < 0) {
+ dev_err(palmas->dev, "POWER_CTRL register update failed %d\n",
+ ret);
+ return ret;
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(palmas_ext_control_req_config);
+
static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
struct palmas_platform_data *pdata)
{
PALMAS_POWER_CTRL_ENABLE2_MASK;
if (i2c->irq)
palmas_set_pdata_irq_flag(i2c, pdata);
+
+ pdata->pm_off = of_property_read_bool(node,
+ "ti,system-power-controller");
+}
+
+static struct palmas *palmas_dev;
+static void palmas_power_off(void)
+{
+ unsigned int addr;
+ int ret, slave;
+
+ if (!palmas_dev)
+ return;
+
+ slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
+ addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL);
+
+ ret = regmap_update_bits(
+ palmas_dev->regmap[slave],
+ addr,
+ PALMAS_DEV_CTRL_DEV_ON,
+ 0);
+
+ if (ret)
+ pr_err("%s: Unable to write to DEV_CTRL_DEV_ON: %d\n",
+ __func__, ret);
}
static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
*/
if (node) {
ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
- if (ret < 0)
+ if (ret < 0) {
goto err_irq;
- else
+ } else if (pdata->pm_off && !pm_power_off) {
+ palmas_dev = palmas;
+ pm_power_off = palmas_power_off;
return ret;
+ }
}
return ret;
{
struct pcf50633_adc *adc;
- adc = kzalloc(sizeof(*adc), GFP_KERNEL);
+ adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
if (!adc)
return -ENOMEM;
kfree(adc->queue[i]);
mutex_unlock(&adc->queue_mutex);
- kfree(adc);
return 0;
}
const struct i2c_device_id *ids)
{
struct pcf50633 *pcf;
- struct pcf50633_platform_data *pdata = client->dev.platform_data;
+ struct pcf50633_platform_data *pdata = dev_get_platdata(&client->dev);
int i, ret;
int version, variant;
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/err.h>
static int pm8921_probe(struct platform_device *pdev)
{
- const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
+ const struct pm8921_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct pm8921 *pmic;
int rc;
u8 val;
return -EINVAL;
}
- pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL);
+ pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
if (!pmic) {
pr_err("Cannot alloc pm8921 struct\n");
return -ENOMEM;
rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
if (rc) {
pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
- goto err_read_rev;
+ return rc;
}
pr_info("PMIC revision 1: %02X\n", val);
rev = val;
if (rc) {
pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
REG_HWREV_2, rc);
- goto err_read_rev;
+ return rc;
}
pr_info("PMIC revision 2: %02X\n", val);
rev |= val << BITS_PER_BYTE;
err:
mfd_remove_devices(pmic->dev);
- platform_set_drvdata(pdev, NULL);
-err_read_rev:
- kfree(pmic);
return rc;
}
pm8xxx_irq_exit(pmic->irq_chip);
pmic->irq_chip = NULL;
}
- platform_set_drvdata(pdev, NULL);
- kfree(pmic);
return 0;
}
const struct i2c_device_id *id)
{
struct rc5t583 *rc5t583;
- struct rc5t583_platform_data *pdata = i2c->dev.platform_data;
+ struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev);
int ret;
bool irq_init_success = false;
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ * Roger Tseng <rogerable@realtek.com>
*/
#include <linux/module.h>
return 0;
}
+static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg1;
+ u8 reg3;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®1);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
+
+ if (!rtsx_vendor_setting_valid(reg1))
+ return;
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg1);
+ pcr->sd30_drive_sel_1v8 =
+ map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1));
+ pcr->card_drive_sel &= 0x3F;
+ pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
+
+ rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, ®3);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
+ pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
+}
+
+static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+
+ if (!rtsx_vendor_setting_valid(reg))
+ return;
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg);
+ pcr->sd30_drive_sel_1v8 =
+ map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
+ pcr->sd30_drive_sel_3v3 =
+ map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
+}
+
+static void rtl8411_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
+}
+
static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
{
- return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0xFF, pcr->sd30_drive_sel_3v3);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+
+ return rtsx_pci_send_cmd(pcr, 100);
}
static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
{
- if (rtl8411b_is_qfn48(pcr))
- rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5);
+ rtsx_pci_init_cmd(pcr);
- return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ if (rtl8411b_is_qfn48(pcr))
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ CARD_PULL_CTL3, 0xFF, 0xF5);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0xFF, pcr->sd30_drive_sel_3v3);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, FUNC_FORCE_CTL,
+ 0x06, 0x00);
+
+ return rtsx_pci_send_cmd(pcr, 100);
}
static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
if (err < 0)
return err;
val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
if (err < 0)
return err;
val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
}
static const struct pcr_ops rtl8411_pcr_ops = {
+ .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
.extra_init_hw = rtl8411_extra_init_hw,
.optimize_phy = NULL,
.turn_on_led = rtl8411_turn_on_led,
.switch_output_voltage = rtl8411_switch_output_voltage,
.cd_deglitch = rtl8411_cd_deglitch,
.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+ .force_power_down = rtl8411_force_power_down,
};
static const struct pcr_ops rtl8411b_pcr_ops = {
+ .fetch_vendor_settings = rtl8411b_fetch_vendor_settings,
.extra_init_hw = rtl8411b_extra_init_hw,
.optimize_phy = NULL,
.turn_on_led = rtl8411_turn_on_led,
.switch_output_voltage = rtl8411_switch_output_voltage,
.cd_deglitch = rtl8411_cd_deglitch,
.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+ .force_power_down = rtl8411_force_power_down,
};
/* SD Pull Control Enable:
pcr->num_slots = 2;
pcr->ops = &rtl8411_pcr_ops;
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
+
pcr->ic_version = rtl8411_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
pcr->num_slots = 2;
pcr->ops = &rtl8411b_pcr_ops;
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
+
pcr->ic_version = rtl8411_get_ic_version(pcr);
if (rtl8411b_is_qfn48(pcr)) {
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/module.h>
return val & 0x0F;
}
-static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr)
+static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
{
- u32 val;
+ u32 reg;
- rtsx_pci_read_config_dword(pcr, 0x724, &val);
- dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val);
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
- if (!(val & 0x80)) {
- if (val & 0x08)
- pcr->ms_pmos = false;
- else
- pcr->ms_pmos = true;
+ if (rts5209_vendor_setting1_valid(reg)) {
+ if (rts5209_reg_check_ms_pmos(reg))
+ pcr->flags |= PCR_MS_PMOS;
+ pcr->aspm_en = rts5209_reg_to_aspm(reg);
}
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+
+ if (rts5209_vendor_setting2_valid(reg)) {
+ pcr->sd30_drive_sel_1v8 =
+ rts5209_reg_to_sd30_drive_sel_1v8(reg);
+ pcr->sd30_drive_sel_3v3 =
+ rts5209_reg_to_sd30_drive_sel_3v3(reg);
+ pcr->card_drive_sel = rts5209_reg_to_card_drive_sel(reg);
+ }
+}
+
+static void rts5209_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
}
static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
/* Turn off LED */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+ /* Force CLKREQ# PIN to drive 0 to request clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
+ /* Configure driving */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0xFF, pcr->sd30_drive_sel_3v3);
return rtsx_pci_send_cmd(pcr, 100);
}
partial_pwr_on = SD_PARTIAL_POWER_ON;
pwr_on = SD_POWER_ON;
- if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
pwr_mask = MS_POWER_MASK;
partial_pwr_on = MS_PARTIAL_POWER_ON;
pwr_on = MS_POWER_ON;
pwr_mask = SD_POWER_MASK;
pwr_off = SD_POWER_OFF;
- if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
pwr_mask = MS_POWER_MASK;
pwr_off = MS_POWER_OFF;
}
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
- LDO3318_PWR_MASK, 0X06);
+ LDO3318_PWR_MASK, 0x06);
return rtsx_pci_send_cmd(pcr, 100);
}
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
return err;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
}
static const struct pcr_ops rts5209_pcr_ops = {
+ .fetch_vendor_settings = rts5209_fetch_vendor_settings,
.extra_init_hw = rts5209_extra_init_hw,
.optimize_phy = rts5209_optimize_phy,
.turn_on_led = rts5209_turn_on_led,
.switch_output_voltage = rts5209_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
+ .force_power_down = rts5209_force_power_down,
};
/* SD Pull Control Enable:
pcr->num_slots = 2;
pcr->ops = &rts5209_pcr_ops;
- rts5209_init_vendor_cfg(pcr);
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTS5209_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 16);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
pcr->ic_version = rts5209_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl;
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- *
* Roger Tseng <rogerable@realtek.com>
- * No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
*/
#include <linux/module.h>
#include "rtsx_pcr.h"
+static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
+{
+ u8 driving_3v3[4][3] = {
+ {0x13, 0x13, 0x13},
+ {0x96, 0x96, 0x96},
+ {0x7F, 0x7F, 0x7F},
+ {0x96, 0x96, 0x96},
+ };
+ u8 driving_1v8[4][3] = {
+ {0x99, 0x99, 0x99},
+ {0xAA, 0xAA, 0xAA},
+ {0xFE, 0xFE, 0xFE},
+ {0xB3, 0xB3, 0xB3},
+ };
+ u8 (*driving)[3], drive_sel;
+
+ if (voltage == OUTPUT_3V3) {
+ driving = driving_3v3;
+ drive_sel = pcr->sd30_drive_sel_3v3;
+ } else {
+ driving = driving_1v8;
+ drive_sel = pcr->sd30_drive_sel_1v8;
+ }
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+ 0xFF, driving[drive_sel][0]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+ 0xFF, driving[drive_sel][1]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+ 0xFF, driving[drive_sel][2]);
+}
+
+static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+
+ if (!rtsx_vendor_setting_valid(reg))
+ return;
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg);
+ pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
+ pcr->card_drive_sel &= 0x3F;
+ pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+ pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
+ if (rtsx_reg_check_reverse_socket(reg))
+ pcr->flags |= PCR_REVERSE_SOCKET;
+}
+
+static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ /* Set relink_time to 0 */
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+ if (pm_state == HOST_ENTER_S3)
+ rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+
+ rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
{
u16 cap;
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
/* Switch LDO3318 source from DV33 to card_3v3 */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
/* Configure OBFF */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
- /* Configure force_clock_req
- * Maybe We should define 0xFF03 as some name
- */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
- /* Correct driving */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_CLK_DRIVE_SEL, 0xFF, 0x96);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_CMD_DRIVE_SEL, 0xFF, 0x96);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_DAT_DRIVE_SEL, 0xFF, 0x96);
+ /* Configure driving */
+ rts5227_fill_driving(pcr, OUTPUT_3V3);
+ /* Configure force_clock_req */
+ if (pcr->flags & PCR_REVERSE_SOCKET)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
+ else
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
int err;
- u8 drive_sel;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
- drive_sel = 0x96;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
if (err < 0)
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24);
if (err < 0)
return err;
- drive_sel = 0xB3;
} else {
return -EINVAL;
}
/* set pad drive */
rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
- 0xFF, drive_sel);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
- 0xFF, drive_sel);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
- 0xFF, drive_sel);
+ rts5227_fill_driving(pcr, voltage);
return rtsx_pci_send_cmd(pcr, 100);
}
static const struct pcr_ops rts5227_pcr_ops = {
+ .fetch_vendor_settings = rts5227_fetch_vendor_settings,
.extra_init_hw = rts5227_extra_init_hw,
.optimize_phy = rts5227_optimize_phy,
.turn_on_led = rts5227_turn_on_led,
.switch_output_voltage = rts5227_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
+ .force_power_down = rts5227_force_power_down,
};
/* SD Pull Control Enable:
pcr->num_slots = 2;
pcr->ops = &rts5227_pcr_ops;
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
+
pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/module.h>
return val & 0x0F;
}
+static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+
+ if (!rtsx_vendor_setting_valid(reg))
+ return;
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg);
+ pcr->sd30_drive_sel_1v8 =
+ map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
+ pcr->card_drive_sel &= 0x3F;
+ pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+ pcr->sd30_drive_sel_3v3 =
+ map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
+}
+
+static void rts5229_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
{
rtsx_pci_init_cmd(pcr);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+ /* Force CLKREQ# PIN to drive 0 to request clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
/* Switch LDO3318 source from DV33 to card_3v3 */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
/* LED shine disabled, set initial shine cycle period */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+ /* Configure driving */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0xFF, pcr->sd30_drive_sel_3v3);
return rtsx_pci_send_cmd(pcr, 100);
}
SD_POWER_MASK | PMOS_STRG_MASK,
SD_POWER_OFF | PMOS_STRG_400mA);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
- LDO3318_PWR_MASK, 0X00);
+ LDO3318_PWR_MASK, 0x00);
return rtsx_pci_send_cmd(pcr, 100);
}
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
return err;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_register(pcr,
- SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+ SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
}
static const struct pcr_ops rts5229_pcr_ops = {
+ .fetch_vendor_settings = rts5229_fetch_vendor_settings,
.extra_init_hw = rts5229_extra_init_hw,
.optimize_phy = rts5229_optimize_phy,
.turn_on_led = rts5229_turn_on_led,
.switch_output_voltage = rts5229_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
+ .force_power_down = rts5229_force_power_down,
};
/* SD Pull Control Enable:
pcr->num_slots = 2;
pcr->ops = &rts5229_pcr_ops;
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 6, 6);
+
pcr->ic_version = rts5229_get_ic_version(pcr);
if (pcr->ic_version == IC_VER_C) {
pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 128, West Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/module.h>
return val & 0x0F;
}
+static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
+{
+ u8 driving_3v3[4][3] = {
+ {0x11, 0x11, 0x11},
+ {0x55, 0x55, 0x5C},
+ {0x99, 0x99, 0x92},
+ {0x99, 0x99, 0x92},
+ };
+ u8 driving_1v8[4][3] = {
+ {0x3C, 0x3C, 0x3C},
+ {0xB3, 0xB3, 0xB3},
+ {0xFE, 0xFE, 0xFE},
+ {0xC4, 0xC4, 0xC4},
+ };
+ u8 (*driving)[3], drive_sel;
+
+ if (voltage == OUTPUT_3V3) {
+ driving = driving_3v3;
+ drive_sel = pcr->sd30_drive_sel_3v3;
+ } else {
+ driving = driving_1v8;
+ drive_sel = pcr->sd30_drive_sel_1v8;
+ }
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+ 0xFF, driving[drive_sel][0]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+ 0xFF, driving[drive_sel][1]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+ 0xFF, driving[drive_sel][2]);
+}
+
+static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+
+ if (!rtsx_vendor_setting_valid(reg))
+ return;
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg);
+ pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
+ pcr->card_drive_sel &= 0x3F;
+ pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+ pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
+ if (rtsx_reg_check_reverse_socket(reg))
+ pcr->flags |= PCR_REVERSE_SOCKET;
+}
+
+static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ /* Set relink_time to 0 */
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+ if (pm_state == HOST_ENTER_S3)
+ rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+
+ rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
{
rtsx_pci_init_cmd(pcr);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
/* Switch LDO3318 source from DV33 to card_3v3 */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
/* LED shine disabled, set initial shine cycle period */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
- /* Correct driving */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
- SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
+ /* Configure driving */
+ rts5249_fill_driving(pcr, OUTPUT_3V3);
+ if (pcr->flags & PCR_REVERSE_SOCKET)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0);
+ else
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
int err;
- u8 clk_drive, cmd_drive, dat_drive;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
if (err < 0)
return err;
- clk_drive = 0x99;
- cmd_drive = 0x99;
- dat_drive = 0x92;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
if (err < 0)
err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24);
if (err < 0)
return err;
- clk_drive = 0xb3;
- cmd_drive = 0xb3;
- dat_drive = 0xb3;
} else {
return -EINVAL;
}
/* set pad drive */
rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
- 0xFF, clk_drive);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
- 0xFF, cmd_drive);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
- 0xFF, dat_drive);
+ rts5249_fill_driving(pcr, voltage);
return rtsx_pci_send_cmd(pcr, 100);
}
static const struct pcr_ops rts5249_pcr_ops = {
+ .fetch_vendor_settings = rts5249_fetch_vendor_settings,
.extra_init_hw = rts5249_extra_init_hw,
.optimize_phy = rts5249_optimize_phy,
.turn_on_led = rts5249_turn_on_led,
.card_power_on = rts5249_card_power_on,
.card_power_off = rts5249_card_power_off,
.switch_output_voltage = rts5249_switch_output_voltage,
+ .force_power_down = rts5249_force_power_down,
};
/* SD Pull Control Enable:
pcr->num_slots = 2;
pcr->ops = &rts5249_pcr_ops;
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
+ pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
+
pcr->ic_version = rts5249_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5249_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl;
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/pci.h>
pcr->state = PDEV_STAT_RUN;
if (pcr->ops->enable_auto_blink)
pcr->ops->enable_auto_blink(pcr);
+
+ if (pcr->aspm_en)
+ rtsx_pci_write_config_byte(pcr, LCTLR, 0);
}
mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200));
[RTSX_MS_CARD] = MS_EXIST
};
- if (!pcr->ms_pmos) {
+ if (!(pcr->flags & PCR_MS_PMOS)) {
/* When using single PMOS, accessing card is not permitted
* if the existing card is not the designated one.
*/
if (pcr->ops->turn_off_led)
pcr->ops->turn_off_led(pcr);
+ if (pcr->aspm_en)
+ rtsx_pci_write_config_byte(pcr, LCTLR, pcr->aspm_en);
+
mutex_unlock(&pcr->pcr_mutex);
}
+static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
+{
+ if (pcr->ops->turn_off_led)
+ pcr->ops->turn_off_led(pcr);
+
+ rtsx_pci_writel(pcr, RTSX_BIER, 0);
+ pcr->bier = 0;
+
+ rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
+ rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, pm_state);
+
+ if (pcr->ops->force_power_down)
+ pcr->ops->force_power_down(pcr, pm_state);
+}
+
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
{
int err;
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, HOST_SLEEP_STATE, 0x03, 0x00);
/* Disable card clock */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 0x1E, 0);
- /* Reset ASPM state to default value */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
/* Reset delink mode */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0);
/* Card driving select */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
- 0x07, DRIVER_TYPE_D);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DRIVE_SEL,
+ 0xFF, pcr->card_drive_sel);
/* Enable SSC Clock */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1,
0xFF, SSC_8X_EN | SSC_SEL_4M);
* 0: ELBI interrupt flag[31:22] & [7:0] only can be write clear
*/
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, NFTS_TX_CTRL, 0x02, 0);
- /* Force CLKREQ# PIN to drive 0 to request clock */
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
+ rtsx_pci_write_config_byte(pcr, LCTLR, 0);
+
/* Enable clk_request_n to enable clock power management */
rtsx_pci_write_config_byte(pcr, 0x81, 1);
/* Enter L1 when host tx idle */
if (!pcr->slots)
return -ENOMEM;
+ if (pcr->ops->fetch_vendor_settings)
+ pcr->ops->fetch_vendor_settings(pcr);
+
+ dev_dbg(&(pcr->pci->dev), "pcr->aspm_en = 0x%x\n", pcr->aspm_en);
+ dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_1v8 = 0x%x\n",
+ pcr->sd30_drive_sel_1v8);
+ dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_3v3 = 0x%x\n",
+ pcr->sd30_drive_sel_3v3);
+ dev_dbg(&(pcr->pci->dev), "pcr->card_drive_sel = 0x%x\n",
+ pcr->card_drive_sel);
+ dev_dbg(&(pcr->pci->dev), "pcr->flags = 0x%x\n", pcr->flags);
+
pcr->state = PDEV_STAT_IDLE;
err = rtsx_pci_init_hw(pcr);
if (err < 0) {
{
struct pcr_handle *handle;
struct rtsx_pcr *pcr;
- int ret = 0;
dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
mutex_lock(&pcr->pcr_mutex);
- if (pcr->ops->turn_off_led)
- pcr->ops->turn_off_led(pcr);
-
- rtsx_pci_writel(pcr, RTSX_BIER, 0);
- pcr->bier = 0;
-
- rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
- rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
+ rtsx_pci_power_off(pcr, HOST_ENTER_S3);
pci_save_state(pcidev);
pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
mutex_unlock(&pcr->pcr_mutex);
- return ret;
+ return 0;
}
static int rtsx_pci_resume(struct pci_dev *pcidev)
return ret;
}
+static void rtsx_pci_shutdown(struct pci_dev *pcidev)
+{
+ struct pcr_handle *handle;
+ struct rtsx_pcr *pcr;
+
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+ handle = pci_get_drvdata(pcidev);
+ pcr = handle->pcr;
+ rtsx_pci_power_off(pcr, HOST_ENTER_S1);
+
+ pci_disable_device(pcidev);
+}
+
#else /* CONFIG_PM */
#define rtsx_pci_suspend NULL
#define rtsx_pci_resume NULL
+#define rtsx_pci_shutdown NULL
#endif /* CONFIG_PM */
.remove = rtsx_pci_remove,
.suspend = rtsx_pci_suspend,
.resume = rtsx_pci_resume,
+ .shutdown = rtsx_pci_shutdown,
};
module_pci_driver(rtsx_pci_driver);
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#ifndef __RTSX_PCR_H
void rts5249_init_params(struct rtsx_pcr *pcr);
void rtl8411b_init_params(struct rtsx_pcr *pcr);
+static inline u8 map_sd_drive(int idx)
+{
+ u8 sd_drive[4] = {
+ 0x01, /* Type D */
+ 0x02, /* Type C */
+ 0x05, /* Type A */
+ 0x03 /* Type B */
+ };
+
+ return sd_drive[idx];
+}
+
+#define rtsx_vendor_setting_valid(reg) (!((reg) & 0x1000000))
+#define rts5209_vendor_setting1_valid(reg) (!((reg) & 0x80))
+#define rts5209_vendor_setting2_valid(reg) ((reg) & 0x80)
+
+#define rtsx_reg_to_aspm(reg) (((reg) >> 28) & 0x03)
+#define rtsx_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 26) & 0x03)
+#define rtsx_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x03)
+#define rtsx_reg_to_card_drive_sel(reg) ((((reg) >> 25) & 0x01) << 6)
+#define rtsx_reg_check_reverse_socket(reg) ((reg) & 0x4000)
+#define rts5209_reg_to_aspm(reg) (((reg) >> 5) & 0x03)
+#define rts5209_reg_check_ms_pmos(reg) (!((reg) & 0x08))
+#define rts5209_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 3) & 0x07)
+#define rts5209_reg_to_sd30_drive_sel_3v3(reg) ((reg) & 0x07)
+#define rts5209_reg_to_card_drive_sel(reg) ((reg) >> 8)
+#define rtl8411_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x07)
+#define rtl8411b_reg_to_sd30_drive_sel_3v3(reg) ((reg) & 0x03)
+
#endif
static struct mfd_cell s2mps11_devs[] = {
{
.name = "s2mps11-pmic",
- },
+ }, {
+ .name = "s2mps11-clk",
+ }
};
#ifdef CONFIG_OF
{ .compatible = "samsung,s5m8767-pmic",
.data = (void *)S5M8767X,
},
+ { .compatible = "samsung,s2mps11-pmic",
+ .data = (void *)S2MPS11X,
+ },
{},
};
#endif
}
EXPORT_SYMBOL_GPL(sec_reg_update);
+static bool s2mps11_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case S2MPS11_REG_INT1M:
+ case S2MPS11_REG_INT2M:
+ case S2MPS11_REG_INT3M:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static bool s5m8763_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case S5M8763_REG_IRQM1:
+ case S5M8763_REG_IRQM2:
+ case S5M8763_REG_IRQM3:
+ case S5M8763_REG_IRQM4:
+ return false;
+ default:
+ return true;
+ }
+}
+
static struct regmap_config sec_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.val_bits = 8,
.max_register = S2MPS11_REG_L38CTRL,
+ .volatile_reg = s2mps11_volatile,
+ .cache_type = REGCACHE_FLAT,
};
static struct regmap_config s5m8763_regmap_config = {
.val_bits = 8,
.max_register = S5M8763_REG_LBCNFG2,
+ .volatile_reg = s5m8763_volatile,
+ .cache_type = REGCACHE_FLAT,
};
static struct regmap_config s5m8767_regmap_config = {
.val_bits = 8,
.max_register = S5M8767_REG_LDO28CTRL,
+ .volatile_reg = s2mps11_volatile,
+ .cache_type = REGCACHE_FLAT,
};
#ifdef CONFIG_OF
static int sec_pmic_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct sec_platform_data *pdata = i2c->dev.platform_data;
+ struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
const struct regmap_config *regmap;
struct sec_pmic_dev *sec_pmic;
int ret;
atomic_set(&core->is_alive, 0);
core->power_state = SI476X_POWER_DOWN;
- pdata = client->dev.platform_data;
+ pdata = dev_get_platdata(&client->dev);
if (pdata) {
memcpy(&core->power_up_parameters,
&pdata->power_up_parameters,
if (!pdev)
return -ENOMEM;
- uart_data = pdev->dev.platform_data;
+ uart_data = dev_get_platdata(&pdev->dev);
if (devices & SM501_USE_UART0) {
sm501_setup_uart_data(sm, uart_data++, 0x30000);
if (!pdev)
return -ENOMEM;
- icd = pdev->dev.platform_data;
+ icd = dev_get_platdata(&pdev->dev);
/* We keep the pin_sda and pin_scl fields relative in case the
* same platform data is passed to >1 SM501.
sm->dev = &dev->dev;
sm->pdev_id = dev->id;
- sm->platdata = dev->dev.platform_data;
+ sm->platdata = dev_get_platdata(&dev->dev);
ret = platform_get_irq(dev, 0);
if (ret < 0) {
void __iomem **regs,
spinlock_t **lock)
{
- struct pci_dev *pdev = *(struct pci_dev **)(dev->dev.platform_data);
+ struct pci_dev *pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev);
struct sta2x11_mfd *mfd;
if (!pdev)
const char *name = sta2x11_mfd_names[index];
struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index];
- pdev = dev->dev.platform_data;
+ pdev = dev_get_platdata(&dev->dev);
mfd = sta2x11_mfd_find(*pdev);
if (!mfd)
return -ENODEV;
return ret;
}
-void stmpe_of_probe(struct stmpe_platform_data *pdata, struct device_node *np)
+static void stmpe_of_probe(struct stmpe_platform_data *pdata,
+ struct device_node *np)
{
struct device_node *child;
static struct platform_driver syscon_driver;
struct syscon {
- void __iomem *base;
struct regmap *regmap;
};
struct device *dev = &pdev->dev;
struct syscon *syscon;
struct resource *res;
+ void __iomem *base;
syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
if (!syscon)
if (!res)
return -ENOENT;
- syscon->base = devm_ioremap(dev, res->start, resource_size(res));
- if (!syscon->base)
+ base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!base)
return -ENOMEM;
syscon_regmap_config.max_register = res->end - res->start - 3;
- syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
+ syscon->regmap = devm_regmap_init_mmio(dev, base,
&syscon_regmap_config);
if (IS_ERR(syscon->regmap)) {
dev_err(dev, "regmap init failed\n");
static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
{
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+ struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
if (pdata && pdata->suspend)
pdata->suspend(dev);
static int t7l66xb_resume(struct platform_device *dev)
{
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+ struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
clk_enable(t7l66xb->clk48m);
if (pdata && pdata->resume)
static int t7l66xb_probe(struct platform_device *dev)
{
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+ struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
struct t7l66xb *t7l66xb;
struct resource *iomem, *rscr;
int ret;
static int t7l66xb_remove(struct platform_device *dev)
{
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+ struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
int ret;
static int tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
+ struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct device_node *np = i2c->dev.of_node;
struct tc3589x *tc3589x;
int ret;
static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
{
struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
- struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+ struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
if (pdata && pdata->suspend)
pdata->suspend(dev);
static int tc6387xb_resume(struct platform_device *dev)
{
struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
- struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+ struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
clk_enable(tc6387xb->clk32k);
if (pdata && pdata->resume)
static int tc6387xb_probe(struct platform_device *dev)
{
- struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+ struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
struct resource *iomem, *rscr;
struct clk *clk32k;
struct tc6387xb *tc6387xb;
static int tc6393xb_probe(struct platform_device *dev)
{
- struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+ struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
struct tc6393xb *tc6393xb;
struct resource *iomem, *rscr;
int ret, temp;
static int tc6393xb_remove(struct platform_device *dev)
{
- struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+ struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
int ret;
#ifdef CONFIG_PM
static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+ struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
int i, ret;
static int tc6393xb_resume(struct platform_device *dev)
{
- struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+ struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
int ret;
int i;
static int ti_ssp_probe(struct platform_device *pdev)
{
static struct ti_ssp *ssp;
- const struct ti_ssp_data *pdata = pdev->dev.platform_data;
+ const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev);
int error = 0, prediv = 0xff, id;
unsigned long sysclk;
struct device *dev = &pdev->dev;
void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
{
spin_lock(&tsadc->reg_lock);
+ tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
tsadc->reg_se_cache |= val;
- spin_unlock(&tsadc->reg_lock);
-
am335x_tsc_se_update(tsadc);
+ spin_unlock(&tsadc->reg_lock);
}
EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
{
spin_lock(&tsadc->reg_lock);
+ tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
tsadc->reg_se_cache &= ~val;
- spin_unlock(&tsadc->reg_lock);
-
am335x_tsc_se_update(tsadc);
+ spin_unlock(&tsadc->reg_lock);
}
EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
clock_rate = clk_get_rate(clk);
clk_put(clk);
clk_value = clock_rate / ADC_CLK;
- if (clk_value < MAX_CLK_DIV) {
- dev_err(&pdev->dev, "clock input less than min clock requirement\n");
- err = -EINVAL;
- goto err_disable_clk;
- }
+
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
clk_value = clk_value - 1;
tscadc_writel(tscadc, REG_CLKDIV, clk_value);
/* Set the control register bits */
ctrl = CNTRLREG_STEPCONFIGWRT |
- CNTRLREG_TSCENB |
- CNTRLREG_STEPID |
- CNTRLREG_4WIRE;
+ CNTRLREG_STEPID;
+ if (tsc_wires > 0)
+ ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
tscadc_writel(tscadc, REG_CTRL, ctrl);
/* Set register bits for Idle Config Mode */
- tscadc_idle_config(tscadc);
+ if (tsc_wires > 0)
+ tscadc_idle_config(tscadc);
/* Enable the TSC module enable bit */
ctrl = tscadc_readl(tscadc, REG_CTRL);
pm_runtime_get_sync(dev);
/* context restore */
- ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
- CNTRLREG_STEPID | CNTRLREG_4WIRE;
+ ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
+ if (tscadc_dev->tsc_cell != -1)
+ ctrl |= CNTRLREG_TSCENB | CNTRLREG_4WIRE;
tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
- tscadc_idle_config(tscadc_dev);
+
+ if (tscadc_dev->tsc_cell != -1)
+ tscadc_idle_config(tscadc_dev);
am335x_tsc_se_update(tscadc_dev);
restore = tscadc_readl(tscadc_dev, REG_CTRL);
tscadc_writel(tscadc_dev, REG_CTRL,
},
};
-const struct max7301_platform_data timberdale_max7301_platform_data = {
+static const struct max7301_platform_data timberdale_max7301_platform_data = {
.base = 200
};
-const struct mc33880_platform_data timberdale_mc33880_platform_data = {
+static const struct mc33880_platform_data timberdale_mc33880_platform_data = {
.base = 100
};
priv->fw.major, priv->fw.minor, ip_setup);
err = -ENODEV;
goto err_mfd;
- break;
}
if (err) {
.remove = timb_remove,
};
-static int __init timberdale_init(void)
-{
- int err;
-
- err = pci_register_driver(&timberdale_pci_driver);
- if (err < 0) {
- printk(KERN_ERR
- "Failed to register PCI driver for %s device.\n",
- timberdale_pci_driver.name);
- return -ENODEV;
- }
-
- printk(KERN_INFO "Driver for %s has been successfully registered.\n",
- timberdale_pci_driver.name);
-
- return 0;
-}
-
-static void __exit timberdale_exit(void)
-{
- pci_unregister_driver(&timberdale_pci_driver);
-
- printk(KERN_INFO "Driver for %s has been successfully unregistered.\n",
- timberdale_pci_driver.name);
-}
-
-module_init(timberdale_init);
-module_exit(timberdale_exit);
+module_pci_driver(timberdale_pci_driver);
MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
MODULE_VERSION(DRV_VERSION);
i2c_set_clientdata(client, tps6105x);
tps6105x->client = client;
- pdata = client->dev.platform_data;
+ pdata = dev_get_platdata(&client->dev);
tps6105x->pdata = pdata;
mutex_init(&tps6105x->lock);
seq_printf(s, "mask2 %s\n", buf);
/* ignore ackint2 */
- schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
-
+ queue_delayed_work(system_power_efficient_wq, &tps->work,
+ POWER_POLL_DELAY);
/* VMAIN voltage, enable lowpower, etc */
value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC1);
&& (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)))
poll = 1;
if (poll)
- schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
+ queue_delayed_work(system_power_efficient_wq, &tps->work,
+ POWER_POLL_DELAY);
/* also potentially gpio-in rise or fall */
}
disable_irq_nosync(irq);
set_bit(FLAG_IRQ_ENABLE, &tps->flags);
- schedule_delayed_work(&tps->work, 0);
+ queue_delayed_work(system_power_efficient_wq, &tps->work, 0);
return IRQ_HANDLED;
}
static int __exit tps65010_remove(struct i2c_client *client)
{
struct tps65010 *tps = i2c_get_clientdata(client);
- struct tps65010_board *board = client->dev.platform_data;
+ struct tps65010_board *board = dev_get_platdata(&client->dev);
if (board && board->teardown) {
int status = board->teardown(client, board->context);
free_irq(client->irq, tps);
cancel_delayed_work_sync(&tps->work);
debugfs_remove(tps->file);
- kfree(tps);
the_tps = NULL;
return 0;
}
{
struct tps65010 *tps;
int status;
- struct tps65010_board *board = client->dev.platform_data;
+ struct tps65010_board *board = dev_get_platdata(&client->dev);
if (the_tps) {
dev_dbg(&client->dev, "only one tps6501x chip allowed\n");
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EINVAL;
- tps = kzalloc(sizeof *tps, GFP_KERNEL);
+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
if (status < 0) {
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
client->irq, status);
- goto fail1;
+ return status;
}
/* annoying race here, ideally we'd have an option
* to claim the irq now and enable it later.
}
return 0;
-fail1:
- kfree(tps);
- return status;
}
static const struct i2c_device_id tps65010_id[] = {
&& test_and_set_bit(
FLAG_VBUS_CHANGED, &the_tps->flags)) {
/* gadget drivers call this in_irq() */
- schedule_delayed_work(&the_tps->work, 0);
+ queue_delayed_work(system_power_efficient_wq, &the_tps->work,
+ 0);
}
local_irq_restore(flags);
static int tps65090_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct tps65090_platform_data *pdata = client->dev.platform_data;
+ struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev);
int irq_base = 0;
struct tps65090 *tps65090;
int ret;
static int tps6586x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct tps6586x_platform_data *pdata = client->dev.platform_data;
+ struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);
struct tps6586x *tps6586x;
int ret;
int tps65912_device_init(struct tps65912 *tps65912)
{
- struct tps65912_board *pmic_plat_data = tps65912->dev->platform_data;
+ struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
struct tps65912_platform_data *init_data;
int ret, dcdc_avs, value;
static int tps80031_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct tps80031_platform_data *pdata = client->dev.platform_data;
+ struct tps80031_platform_data *pdata = dev_get_platdata(&client->dev);
struct tps80031 *tps80031;
int ret;
uint8_t es_version;
static int
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct twl4030_platform_data *pdata = client->dev.platform_data;
+ struct twl4030_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
struct platform_device *pdev;
struct regmap_config *twl_regmap_config;
static int twl4030_audio_probe(struct platform_device *pdev)
{
struct twl4030_audio *audio;
- struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+ struct twl4030_audio_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node;
struct mfd_cell *cell = NULL;
int ret, childs = 0;
static int twl4030_madc_probe(struct platform_device *pdev)
{
struct twl4030_madc_data *madc;
- struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
+ struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
int ret;
u8 regval;
return err;
}
-int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
+static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
{
int err;
int i;
return 0;
}
-int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
+static int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
{
struct twl4030_resconfig *resconfig = pdata->resource_config;
int err;
return false;
}
-int twl4030_power_probe(struct platform_device *pdev)
+static int twl4030_power_probe(struct platform_device *pdev)
{
- struct twl4030_power_data *pdata = pdev->dev.platform_data;
+ struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node;
int err = 0;
int err2 = 0;
#include <linux/suspend.h>
#include <linux/of.h>
#include <linux/irqdomain.h>
+#include <linux/of_device.h>
#include "twl-core.h"
CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */
RSV_INTR_OFFSET, /* Bit 23 Reserved */
};
+
+static int twl6032_interrupt_mapping[24] = {
+ PWR_INTR_OFFSET, /* Bit 0 PWRON */
+ PWR_INTR_OFFSET, /* Bit 1 RPWRON */
+ PWR_INTR_OFFSET, /* Bit 2 SYS_VLOW */
+ RTC_INTR_OFFSET, /* Bit 3 RTC_ALARM */
+ RTC_INTR_OFFSET, /* Bit 4 RTC_PERIOD */
+ HOTDIE_INTR_OFFSET, /* Bit 5 HOT_DIE */
+ SMPSLDO_INTR_OFFSET, /* Bit 6 VXXX_SHORT */
+ PWR_INTR_OFFSET, /* Bit 7 SPDURATION */
+
+ PWR_INTR_OFFSET, /* Bit 8 WATCHDOG */
+ BATDETECT_INTR_OFFSET, /* Bit 9 BAT */
+ SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */
+ MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */
+ MADC_INTR_OFFSET, /* Bit 12 GPADC_RT_EOC */
+ MADC_INTR_OFFSET, /* Bit 13 GPADC_SW_EOC */
+ GASGAUGE_INTR_OFFSET, /* Bit 14 CC_EOC */
+ GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */
+
+ USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */
+ USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */
+ USBOTG_INTR_OFFSET, /* Bit 18 ID */
+ USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */
+ CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */
+ CHARGERFAULT_INTR_OFFSET, /* Bit 21 EXT_CHRG */
+ CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */
+ RSV_INTR_OFFSET, /* Bit 23 Reserved */
+};
+
/*----------------------------------------------------------------------*/
-static unsigned twl6030_irq_base;
-static int twl_irq;
-static bool twl_irq_wake_enabled;
+struct twl6030_irq {
+ unsigned int irq_base;
+ int twl_irq;
+ bool irq_wake_enabled;
+ atomic_t wakeirqs;
+ struct notifier_block pm_nb;
+ struct irq_chip irq_chip;
+ struct irq_domain *irq_domain;
+ const int *irq_mapping_tbl;
+};
-static struct completion irq_event;
-static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0);
+static struct twl6030_irq *twl6030_irq;
static int twl6030_irq_pm_notifier(struct notifier_block *notifier,
unsigned long pm_event, void *unused)
{
int chained_wakeups;
+ struct twl6030_irq *pdata = container_of(notifier, struct twl6030_irq,
+ pm_nb);
switch (pm_event) {
case PM_SUSPEND_PREPARE:
- chained_wakeups = atomic_read(&twl6030_wakeirqs);
+ chained_wakeups = atomic_read(&pdata->wakeirqs);
- if (chained_wakeups && !twl_irq_wake_enabled) {
- if (enable_irq_wake(twl_irq))
+ if (chained_wakeups && !pdata->irq_wake_enabled) {
+ if (enable_irq_wake(pdata->twl_irq))
pr_err("twl6030 IRQ wake enable failed\n");
else
- twl_irq_wake_enabled = true;
- } else if (!chained_wakeups && twl_irq_wake_enabled) {
- disable_irq_wake(twl_irq);
- twl_irq_wake_enabled = false;
+ pdata->irq_wake_enabled = true;
+ } else if (!chained_wakeups && pdata->irq_wake_enabled) {
+ disable_irq_wake(pdata->twl_irq);
+ pdata->irq_wake_enabled = false;
}
- disable_irq(twl_irq);
+ disable_irq(pdata->twl_irq);
break;
case PM_POST_SUSPEND:
- enable_irq(twl_irq);
+ enable_irq(pdata->twl_irq);
break;
default:
return NOTIFY_DONE;
}
-static struct notifier_block twl6030_irq_pm_notifier_block = {
- .notifier_call = twl6030_irq_pm_notifier,
-};
-
/*
- * This thread processes interrupts reported by the Primary Interrupt Handler.
- */
-static int twl6030_irq_thread(void *data)
+* Threaded irq handler for the twl6030 interrupt.
+* We query the interrupt controller in the twl6030 to determine
+* which module is generating the interrupt request and call
+* handle_nested_irq for that module.
+*/
+static irqreturn_t twl6030_irq_thread(int irq, void *data)
{
- long irq = (long)data;
- static unsigned i2c_errors;
- static const unsigned max_i2c_errors = 100;
- int ret;
-
- while (!kthread_should_stop()) {
- int i;
- union {
+ int i, ret;
+ union {
u8 bytes[4];
u32 int_sts;
- } sts;
-
- /* Wait for IRQ, then read PIH irq status (also blocking) */
- wait_for_completion_interruptible(&irq_event);
-
- /* read INT_STS_A, B and C in one shot using a burst read */
- ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes,
- REG_INT_STS_A, 3);
- if (ret) {
- pr_warning("twl6030: I2C error %d reading PIH ISR\n",
- ret);
- if (++i2c_errors >= max_i2c_errors) {
- printk(KERN_ERR "Maximum I2C error count"
- " exceeded. Terminating %s.\n",
- __func__);
- break;
- }
- complete(&irq_event);
- continue;
- }
-
-
+ } sts;
+ struct twl6030_irq *pdata = data;
+
+ /* read INT_STS_A, B and C in one shot using a burst read */
+ ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes, REG_INT_STS_A, 3);
+ if (ret) {
+ pr_warn("twl6030_irq: I2C error %d reading PIH ISR\n", ret);
+ return IRQ_HANDLED;
+ }
- sts.bytes[3] = 0; /* Only 24 bits are valid*/
+ sts.bytes[3] = 0; /* Only 24 bits are valid*/
- /*
- * Since VBUS status bit is not reliable for VBUS disconnect
- * use CHARGER VBUS detection status bit instead.
- */
- if (sts.bytes[2] & 0x10)
- sts.bytes[2] |= 0x08;
-
- for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) {
- local_irq_disable();
- if (sts.int_sts & 0x1) {
- int module_irq = twl6030_irq_base +
- twl6030_interrupt_mapping[i];
- generic_handle_irq(module_irq);
-
- }
- local_irq_enable();
+ /*
+ * Since VBUS status bit is not reliable for VBUS disconnect
+ * use CHARGER VBUS detection status bit instead.
+ */
+ if (sts.bytes[2] & 0x10)
+ sts.bytes[2] |= 0x08;
+
+ for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++)
+ if (sts.int_sts & 0x1) {
+ int module_irq =
+ irq_find_mapping(pdata->irq_domain,
+ pdata->irq_mapping_tbl[i]);
+ if (module_irq)
+ handle_nested_irq(module_irq);
+ else
+ pr_err("twl6030_irq: Unmapped PIH ISR %u detected\n",
+ i);
+ pr_debug("twl6030_irq: PIH ISR %u, virq%u\n",
+ i, module_irq);
}
- /*
- * NOTE:
- * Simulation confirms that documentation is wrong w.r.t the
- * interrupt status clear operation. A single *byte* write to
- * any one of STS_A to STS_C register results in all three
- * STS registers being reset. Since it does not matter which
- * value is written, all three registers are cleared on a
- * single byte write, so we just use 0x0 to clear.
- */
- ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A);
- if (ret)
- pr_warning("twl6030: I2C error in clearing PIH ISR\n");
-
- enable_irq(irq);
- }
-
- return 0;
-}
+ /*
+ * NOTE:
+ * Simulation confirms that documentation is wrong w.r.t the
+ * interrupt status clear operation. A single *byte* write to
+ * any one of STS_A to STS_C register results in all three
+ * STS registers being reset. Since it does not matter which
+ * value is written, all three registers are cleared on a
+ * single byte write, so we just use 0x0 to clear.
+ */
+ ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A);
+ if (ret)
+ pr_warn("twl6030_irq: I2C error in clearing PIH ISR\n");
-/*
- * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt.
- * This is a chained interrupt, so there is no desc->action method for it.
- * Now we need to query the interrupt controller in the twl6030 to determine
- * which module is generating the interrupt request. However, we can't do i2c
- * transactions in interrupt context, so we must defer that work to a kernel
- * thread. All we do here is acknowledge and mask the interrupt and wakeup
- * the kernel thread.
- */
-static irqreturn_t handle_twl6030_pih(int irq, void *devid)
-{
- disable_irq_nosync(irq);
- complete(devid);
return IRQ_HANDLED;
}
/*----------------------------------------------------------------------*/
-static inline void activate_irq(int irq)
-{
-#ifdef CONFIG_ARM
- /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
- * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE.
- */
- set_irq_flags(irq, IRQF_VALID);
-#else
- /* same effect on other architectures */
- irq_set_noprobe(irq);
-#endif
-}
-
static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on)
{
+ struct twl6030_irq *pdata = irq_get_chip_data(d->irq);
+
if (on)
- atomic_inc(&twl6030_wakeirqs);
+ atomic_inc(&pdata->wakeirqs);
else
- atomic_dec(&twl6030_wakeirqs);
+ atomic_dec(&pdata->wakeirqs);
return 0;
}
return ret;
}
- return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
+ return irq_find_mapping(twl6030_irq->irq_domain,
+ MMCDETECT_INTR_OFFSET);
}
EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
}
EXPORT_SYMBOL(twl6030_mmc_card_detect);
+static int twl6030_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ struct twl6030_irq *pdata = d->host_data;
+
+ irq_set_chip_data(virq, pdata);
+ irq_set_chip_and_handler(virq, &pdata->irq_chip, handle_simple_irq);
+ irq_set_nested_thread(virq, true);
+ irq_set_parent(virq, pdata->twl_irq);
+
+#ifdef CONFIG_ARM
+ /*
+ * ARM requires an extra step to clear IRQ_NOREQUEST, which it
+ * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE.
+ */
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ /* same effect on other architectures */
+ irq_set_noprobe(virq);
+#endif
+
+ return 0;
+}
+
+static void twl6030_irq_unmap(struct irq_domain *d, unsigned int virq)
+{
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, 0);
+#endif
+ irq_set_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops twl6030_irq_domain_ops = {
+ .map = twl6030_irq_map,
+ .unmap = twl6030_irq_unmap,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+static const struct of_device_id twl6030_of_match[] = {
+ {.compatible = "ti,twl6030", &twl6030_interrupt_mapping},
+ {.compatible = "ti,twl6032", &twl6032_interrupt_mapping},
+ { },
+};
+
int twl6030_init_irq(struct device *dev, int irq_num)
{
struct device_node *node = dev->of_node;
- int nr_irqs, irq_base, irq_end;
- struct task_struct *task;
- static struct irq_chip twl6030_irq_chip;
- int status = 0;
- int i;
+ int nr_irqs;
+ int status;
u8 mask[3];
+ const struct of_device_id *of_id;
- nr_irqs = TWL6030_NR_IRQS;
-
- irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
- if (IS_ERR_VALUE(irq_base)) {
- dev_err(dev, "Fail to allocate IRQ descs\n");
- return irq_base;
+ of_id = of_match_device(twl6030_of_match, dev);
+ if (!of_id || !of_id->data) {
+ dev_err(dev, "Unknown TWL device model\n");
+ return -EINVAL;
}
- irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
- &irq_domain_simple_ops, NULL);
+ nr_irqs = TWL6030_NR_IRQS;
- irq_end = irq_base + nr_irqs;
+ twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL);
+ if (!twl6030_irq) {
+ dev_err(dev, "twl6030_irq: Memory allocation failed\n");
+ return -ENOMEM;
+ }
mask[0] = 0xFF;
mask[1] = 0xFF;
mask[2] = 0xFF;
/* mask all int lines */
- twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
+ status = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
/* mask all int sts */
- twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
+ status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
/* clear INT_STS_A,B,C */
- twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
+ status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
- twl6030_irq_base = irq_base;
+ if (status < 0) {
+ dev_err(dev, "I2C err writing TWL_MODULE_PIH: %d\n", status);
+ return status;
+ }
/*
* install an irq handler for each of the modules;
* clone dummy irq_chip since PIH can't *do* anything
*/
- twl6030_irq_chip = dummy_irq_chip;
- twl6030_irq_chip.name = "twl6030";
- twl6030_irq_chip.irq_set_type = NULL;
- twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake;
-
- for (i = irq_base; i < irq_end; i++) {
- irq_set_chip_and_handler(i, &twl6030_irq_chip,
- handle_simple_irq);
- irq_set_chip_data(i, (void *)irq_num);
- activate_irq(i);
+ twl6030_irq->irq_chip = dummy_irq_chip;
+ twl6030_irq->irq_chip.name = "twl6030";
+ twl6030_irq->irq_chip.irq_set_type = NULL;
+ twl6030_irq->irq_chip.irq_set_wake = twl6030_irq_set_wake;
+
+ twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier;
+ atomic_set(&twl6030_irq->wakeirqs, 0);
+ twl6030_irq->irq_mapping_tbl = of_id->data;
+
+ twl6030_irq->irq_domain =
+ irq_domain_add_linear(node, nr_irqs,
+ &twl6030_irq_domain_ops, twl6030_irq);
+ if (!twl6030_irq->irq_domain) {
+ dev_err(dev, "Can't add irq_domain\n");
+ return -ENOMEM;
}
- dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n",
- irq_num, irq_base, irq_end);
+ dev_info(dev, "PIH (irq %d) nested IRQs\n", irq_num);
/* install an irq handler to demultiplex the TWL6030 interrupt */
- init_completion(&irq_event);
-
- status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH",
- &irq_event);
+ status = request_threaded_irq(irq_num, NULL, twl6030_irq_thread,
+ IRQF_ONESHOT, "TWL6030-PIH", twl6030_irq);
if (status < 0) {
dev_err(dev, "could not claim irq %d: %d\n", irq_num, status);
goto fail_irq;
}
- task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
- if (IS_ERR(task)) {
- dev_err(dev, "could not create irq %d thread!\n", irq_num);
- status = PTR_ERR(task);
- goto fail_kthread;
- }
-
- twl_irq = irq_num;
- register_pm_notifier(&twl6030_irq_pm_notifier_block);
- return irq_base;
-
-fail_kthread:
- free_irq(irq_num, &irq_event);
+ twl6030_irq->twl_irq = irq_num;
+ register_pm_notifier(&twl6030_irq->pm_nb);
+ return 0;
fail_irq:
- for (i = irq_base; i < irq_end; i++)
- irq_set_chip_and_handler(i, NULL, NULL);
-
+ irq_domain_remove(twl6030_irq->irq_domain);
return status;
}
int twl6030_exit_irq(void)
{
- unregister_pm_notifier(&twl6030_irq_pm_notifier_block);
-
- if (twl6030_irq_base) {
- pr_err("twl6030: can't yet clean up IRQs?\n");
- return -ENOSYS;
+ if (twl6030_irq && twl6030_irq->twl_irq) {
+ unregister_pm_notifier(&twl6030_irq->pm_nb);
+ free_irq(twl6030_irq->twl_irq, NULL);
+ /*
+ * TODO: IRQ domain and allocated nested IRQ descriptors
+ * should be freed somehow here. Now It can't be done, because
+ * child devices will not be deleted during removing of
+ * TWL Core driver and they will still contain allocated
+ * virt IRQs in their Resources tables.
+ * The same prevents us from using devm_request_threaded_irq()
+ * in this module.
+ */
}
return 0;
}
#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
#define TWL6040_NUM_SUPPLIES (2)
-static bool twl6040_has_vibra(struct twl6040_platform_data *pdata,
- struct device_node *node)
+static bool twl6040_has_vibra(struct device_node *node)
{
- if (pdata && pdata->vibra)
- return true;
-
#ifdef CONFIG_OF
if (of_find_node_by_name(node, "vibra"))
return true;
#endif
-
return false;
}
int ret;
unsigned int val;
- /* Vibra control registers from cache */
- if (unlikely(reg == TWL6040_REG_VIBCTLL ||
- reg == TWL6040_REG_VIBCTLR)) {
- val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
- } else {
- ret = regmap_read(twl6040->regmap, reg, &val);
- if (ret < 0)
- return ret;
- }
+ ret = regmap_read(twl6040->regmap, reg, &val);
+ if (ret < 0)
+ return ret;
return val;
}
int ret;
ret = regmap_write(twl6040->regmap, reg, val);
- /* Cache the vibra control registers */
- if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
- twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
return ret;
}
/* Get the combined status of the vibra control register */
int twl6040_get_vibralr_status(struct twl6040 *twl6040)
{
+ unsigned int reg;
+ int ret;
u8 status;
- status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1];
+ ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLL, ®);
+ if (ret != 0)
+ return ret;
+ status = reg;
+
+ ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLR, ®);
+ if (ret != 0)
+ return ret;
+ status |= reg;
+
status &= (TWL6040_VIBENA | TWL6040_VIBSEL);
return status;
return true;
}
+static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TWL6040_REG_VIBCTLL:
+ case TWL6040_REG_VIBCTLR:
+ case TWL6040_REG_INTMR:
+ return false;
+ default:
+ return true;
+ }
+}
+
static struct regmap_config twl6040_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = TWL6040_REG_STATUS, /* 0x2e */
.readable_reg = twl6040_readable_reg,
+ .volatile_reg = twl6040_volatile_reg,
+
+ .cache_type = REGCACHE_RBTREE,
};
static const struct regmap_irq twl6040_irqs[] = {
static int twl6040_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct twl6040_platform_data *pdata = client->dev.platform_data;
struct device_node *node = client->dev.of_node;
struct twl6040 *twl6040;
struct mfd_cell *cell = NULL;
int irq, ret, children = 0;
- if (!pdata && !node) {
- dev_err(&client->dev, "Platform data is missing\n");
+ if (!node) {
+ dev_err(&client->dev, "of node is missing\n");
return -EINVAL;
}
twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
GFP_KERNEL);
- if (!twl6040) {
- ret = -ENOMEM;
- goto err;
- }
+ if (!twl6040)
+ return -ENOMEM;
twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config);
- if (IS_ERR(twl6040->regmap)) {
- ret = PTR_ERR(twl6040->regmap);
- goto err;
- }
+ if (IS_ERR(twl6040->regmap))
+ return PTR_ERR(twl6040->regmap);
i2c_set_clientdata(client, twl6040);
twl6040->supplies[0].supply = "vio";
twl6040->supplies[1].supply = "v2v1";
ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
- twl6040->supplies);
+ twl6040->supplies);
if (ret != 0) {
dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
goto regulator_get_err;
twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
/* ERRATA: Automatic power-up is not possible in ES1.0 */
- if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) {
- if (pdata)
- twl6040->audpwron = pdata->audpwron_gpio;
- else
- twl6040->audpwron = of_get_named_gpio(node,
- "ti,audpwron-gpio", 0);
- } else
+ if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
+ twl6040->audpwron = of_get_named_gpio(node,
+ "ti,audpwron-gpio", 0);
+ else
twl6040->audpwron = -EINVAL;
if (gpio_is_valid(twl6040->audpwron)) {
ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
- GPIOF_OUT_INIT_LOW, "audpwron");
+ GPIOF_OUT_INIT_LOW, "audpwron");
if (ret)
goto gpio_err;
}
- ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq,
- IRQF_ONESHOT, 0, &twl6040_irq_chip,
- &twl6040->irq_data);
+ ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT,
+ 0, &twl6040_irq_chip,&twl6040->irq_data);
if (ret < 0)
goto gpio_err;
twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data,
- TWL6040_IRQ_READY);
+ TWL6040_IRQ_READY);
twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data,
- TWL6040_IRQ_TH);
+ TWL6040_IRQ_TH);
ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL,
- twl6040_readyint_handler, IRQF_ONESHOT,
- "twl6040_irq_ready", twl6040);
+ twl6040_readyint_handler, IRQF_ONESHOT,
+ "twl6040_irq_ready", twl6040);
if (ret) {
dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret);
goto readyirq_err;
}
ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL,
- twl6040_thint_handler, IRQF_ONESHOT,
- "twl6040_irq_th", twl6040);
+ twl6040_thint_handler, IRQF_ONESHOT,
+ "twl6040_irq_th", twl6040);
if (ret) {
dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
goto thirq_err;
/*
* The main functionality of twl6040 to provide audio on OMAP4+ systems.
* We can add the ASoC codec child whenever this driver has been loaded.
- * The ASoC codec can work without pdata, pass the platform_data only if
- * it has been provided.
*/
irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG);
cell = &twl6040->cells[children];
twl6040_codec_rsrc[0].end = irq;
cell->resources = twl6040_codec_rsrc;
cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc);
- if (pdata && pdata->codec) {
- cell->platform_data = pdata->codec;
- cell->pdata_size = sizeof(*pdata->codec);
- }
children++;
- if (twl6040_has_vibra(pdata, node)) {
+ /* Vibra input driver support */
+ if (twl6040_has_vibra(node)) {
irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB);
cell = &twl6040->cells[children];
twl6040_vibra_rsrc[0].end = irq;
cell->resources = twl6040_vibra_rsrc;
cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc);
-
- if (pdata && pdata->vibra) {
- cell->platform_data = pdata->vibra;
- cell->pdata_size = sizeof(*pdata->vibra);
- }
children++;
}
- /*
- * Enable the GPO driver in the following cases:
- * DT booted kernel or legacy boot with valid gpo platform_data
- */
- if (!pdata || (pdata && pdata->gpo)) {
- cell = &twl6040->cells[children];
- cell->name = "twl6040-gpo";
-
- if (pdata) {
- cell->platform_data = pdata->gpo;
- cell->pdata_size = sizeof(*pdata->gpo);
- }
- children++;
- }
+ /* GPO support */
+ cell = &twl6040->cells[children];
+ cell->name = "twl6040-gpo";
+ children++;
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
NULL, 0, NULL);
regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
regulator_get_err:
i2c_set_clientdata(client, NULL);
-err:
+
return ret;
}
struct ucb1400_ts ucb_ts;
struct ucb1400_gpio ucb_gpio;
struct snd_ac97 *ac97;
- struct ucb1400_pdata *pdata = dev->platform_data;
+ struct ucb1400_pdata *pdata = dev_get_platdata(dev);
memset(&ucb_ts, 0, sizeof(ucb_ts));
memset(&ucb_gpio, 0, sizeof(ucb_gpio));
static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
{
struct ucb1x00_dev *dev;
- int ret = -ENOMEM;
+ int ret;
dev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
- if (dev) {
- dev->ucb = ucb;
- dev->drv = drv;
-
- ret = drv->add(dev);
-
- if (ret == 0) {
- list_add_tail(&dev->dev_node, &ucb->devs);
- list_add_tail(&dev->drv_node, &drv->devs);
- } else {
- kfree(dev);
- }
+ if (!dev)
+ return -ENOMEM;
+
+ dev->ucb = ucb;
+ dev->drv = drv;
+
+ ret = drv->add(dev);
+ if (ret) {
+ kfree(dev);
+ return ret;
}
+
+ list_add_tail(&dev->dev_node, &ucb->devs);
+ list_add_tail(&dev->drv_node, &drv->devs);
+
return ret;
}
mutex_unlock(&ucb1x00_mutex);
}
+#ifdef CONFIG_PM_SLEEP
static int ucb1x00_suspend(struct device *dev)
{
- struct ucb1x00_plat_data *pdata = dev->platform_data;
+ struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
struct ucb1x00 *ucb = dev_get_drvdata(dev);
struct ucb1x00_dev *udev;
static int ucb1x00_resume(struct device *dev)
{
- struct ucb1x00_plat_data *pdata = dev->platform_data;
+ struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
struct ucb1x00 *ucb = dev_get_drvdata(dev);
struct ucb1x00_dev *udev;
mutex_unlock(&ucb1x00_mutex);
return 0;
}
+#endif
static const struct dev_pm_ops ucb1x00_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
static int wl1273_core_remove(struct i2c_client *client)
{
- struct wl1273_core *core = i2c_get_clientdata(client);
-
dev_dbg(&client->dev, "%s\n", __func__);
mfd_remove_devices(&client->dev);
- kfree(core);
return 0;
}
static int wl1273_core_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
+ struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
struct wl1273_core *core;
struct mfd_cell *cell;
int children = 0;
return -EINVAL;
}
- core = kzalloc(sizeof(*core), GFP_KERNEL);
+ core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
if (!core)
return -ENOMEM;
err:
pdata->free_resources();
- kfree(core);
dev_dbg(&client->dev, "%s\n", __func__);
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
{ 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */
{ 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
+ { 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
{ 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */
{ 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */
{ 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */
{ 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */
+ { 0x00000187, 0x0001 }, /* R390 - FLL1 Synchroniser 7 */
{ 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */
{ 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */
{ 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
{ 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
+ { 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
{ 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */
{ 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */
{ 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */
{ 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */
+ { 0x000001A7, 0x0001 }, /* R422 - FLL2 Synchroniser 7 */
{ 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */
{ 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */
{ 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */
{ 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
+ { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */
+ { 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
+ { 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */
+ { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
+ { 0x000002A9, 0x300A }, /* R681 - Mic Detect Level 4 */
{ 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */
{ 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */
{ 0x00000300, 0x0000 }, /* R768 - Input Enables */
case ARIZONA_FLL1_CONTROL_4:
case ARIZONA_FLL1_CONTROL_5:
case ARIZONA_FLL1_CONTROL_6:
+ case ARIZONA_FLL1_CONTROL_7:
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
case ARIZONA_FLL1_NCO_TEST_0:
case ARIZONA_FLL1_SYNCHRONISER_1:
case ARIZONA_FLL1_SYNCHRONISER_4:
case ARIZONA_FLL1_SYNCHRONISER_5:
case ARIZONA_FLL1_SYNCHRONISER_6:
+ case ARIZONA_FLL1_SYNCHRONISER_7:
case ARIZONA_FLL1_SPREAD_SPECTRUM:
case ARIZONA_FLL1_GPIO_CLOCK:
case ARIZONA_FLL2_CONTROL_1:
case ARIZONA_FLL2_CONTROL_4:
case ARIZONA_FLL2_CONTROL_5:
case ARIZONA_FLL2_CONTROL_6:
+ case ARIZONA_FLL2_CONTROL_7:
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_FLL2_SYNCHRONISER_1:
case ARIZONA_FLL2_SYNCHRONISER_4:
case ARIZONA_FLL2_SYNCHRONISER_5:
case ARIZONA_FLL2_SYNCHRONISER_6:
+ case ARIZONA_FLL2_SYNCHRONISER_7:
case ARIZONA_FLL2_SPREAD_SPECTRUM:
case ARIZONA_FLL2_GPIO_CLOCK:
case ARIZONA_MIC_CHARGE_PUMP_1:
case ARIZONA_MIC_DETECT_1:
case ARIZONA_MIC_DETECT_2:
case ARIZONA_MIC_DETECT_3:
+ case ARIZONA_MIC_DETECT_LEVEL_1:
+ case ARIZONA_MIC_DETECT_LEVEL_2:
+ case ARIZONA_MIC_DETECT_LEVEL_3:
+ case ARIZONA_MIC_DETECT_LEVEL_4:
case ARIZONA_MIC_NOISE_MIX_CONTROL_1:
case ARIZONA_JACK_DETECT_ANALOGUE:
case ARIZONA_INPUT_ENABLES:
case ARIZONA_IRQ_PIN_STATUS:
case ARIZONA_AOD_IRQ1:
case ARIZONA_AOD_IRQ2:
+ case ARIZONA_FX_CTRL2:
case ARIZONA_ASRC_STATUS:
case ARIZONA_DSP_STATUS:
case ARIZONA_DSP1_CONTROL_1:
*/
int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
{
- struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+ struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
int rev, wm831x_num;
enum wm831x_parent parent;
int ret, i;
int wm831x_irq_init(struct wm831x *wm831x, int irq)
{
- struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+ struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
struct irq_domain *domain;
int i, ret, irq_base;
if (wm831x == NULL)
return -ENOMEM;
- spi->bits_per_word = 16;
spi->mode = SPI_MODE_0;
spi_set_drvdata(spi, wm831x);
const struct i2c_device_id *id)
{
struct wm8350 *wm8350;
+ struct wm8350_platform_data *pdata = dev_get_platdata(&i2c->dev);
int ret = 0;
wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL);
i2c_set_clientdata(i2c, wm8350);
wm8350->dev = &i2c->dev;
- return wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data);
+ return wm8350_device_init(wm8350, i2c->irq, pdata);
}
static int wm8350_i2c_remove(struct i2c_client *i2c)
wm8400->dev = &i2c->dev;
i2c_set_clientdata(i2c, wm8400);
- ret = wm8400_init(wm8400, i2c->dev.platform_data);
+ ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
if (ret != 0)
goto err;
int ret;
/* Don't actually go through with the suspend if the CODEC is
- * still active (eg, for audio passthrough from CP. */
- ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
- if (ret < 0) {
- dev_err(dev, "Failed to read power status: %d\n", ret);
- } else if (ret & WM8994_VMID_SEL_MASK) {
- dev_dbg(dev, "CODEC still active, ignoring suspend\n");
- return 0;
- }
-
- ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
- if (ret < 0) {
- dev_err(dev, "Failed to read power status: %d\n", ret);
- } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
- WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
- WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
- dev_dbg(dev, "CODEC still active, ignoring suspend\n");
- return 0;
- }
-
- ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
- if (ret < 0) {
- dev_err(dev, "Failed to read power status: %d\n", ret);
- } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
- WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
- WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
- dev_dbg(dev, "CODEC still active, ignoring suspend\n");
- return 0;
- }
-
+ * still active for accessory detect. */
switch (wm8994->type) {
case WM8958:
case WM1811:
break;
}
- switch (wm8994->type) {
- case WM1811:
- ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
- if (ret < 0) {
- dev_err(dev, "Failed to read jackdet: %d\n", ret);
- } else if (ret & WM1811_JACKDET_MODE_MASK) {
- dev_dbg(dev, "CODEC still active, ignoring suspend\n");
- return 0;
- }
- break;
- default:
- break;
- }
-
/* Disable LDO pulldowns while the device is suspended if we
* don't know that something will be driving them. */
if (!wm8994->ldo_ena_always_driven)
{
int ret;
unsigned long irqflags;
- struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev);
if (!wm8994->irq) {
dev_warn(wm8994->dev,
/* Realtek PCI-Express SD/MMC Card Interface driver
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#include <linux/module.h>
bool double_clk;
bool eject;
bool initial_mode;
- bool ddr_mode;
int power_state;
#define SDMMC_POWER_ON 1
#define SDMMC_POWER_OFF 0
int stat_idx = 0;
u8 rsp_type;
int rsp_len = 5;
+ bool clock_toggled = false;
dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
__func__, cmd_idx, arg);
0xFF, SD_CLK_TOGGLE_EN);
if (err < 0)
goto out;
+
+ clock_toggled = true;
}
rtsx_pci_init_cmd(pcr);
out:
cmd->error = err;
+
+ if (err && clock_toggled)
+ rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
}
static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
kfree(buf);
}
-static int sd_change_phase(struct realtek_pci_sdmmc *host, u8 sample_point)
+static int sd_change_phase(struct realtek_pci_sdmmc *host,
+ u8 sample_point, bool rx)
{
struct rtsx_pcr *pcr = host->pcr;
int err;
- dev_dbg(sdmmc_dev(host), "%s: sample_point = %d\n",
- __func__, sample_point);
+ dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n",
+ __func__, rx ? "RX" : "TX", sample_point);
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPRX_CTL, 0x1F, sample_point);
+ if (rx)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ SD_VPRX_CTL, 0x1F, sample_point);
+ else
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ SD_VPTX_CTL, 0x1F, sample_point);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
PHASE_NOT_RESET, PHASE_NOT_RESET);
int err;
u8 cmd[5] = {0};
- err = sd_change_phase(host, sample_point);
+ err = sd_change_phase(host, sample_point, true);
if (err < 0)
return err;
if (final_phase == 0xFF)
return -EINVAL;
- err = sd_change_phase(host, final_phase);
+ err = sd_change_phase(host, final_phase, true);
if (err < 0)
return err;
} else {
return err;
}
-static int sd_set_timing(struct realtek_pci_sdmmc *host,
- unsigned char timing, bool *ddr_mode)
+static int sd_set_timing(struct realtek_pci_sdmmc *host, unsigned char timing)
{
struct rtsx_pcr *pcr = host->pcr;
int err = 0;
- *ddr_mode = false;
-
rtsx_pci_init_cmd(pcr);
switch (timing) {
break;
case MMC_TIMING_UHS_DDR50:
- *ddr_mode = true;
-
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
0x0C | SD_ASYNC_FIFO_NOT_RST,
SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST);
sd_set_bus_width(host, ios->bus_width);
sd_set_power_mode(host, ios->power_mode);
- sd_set_timing(host, ios->timing, &host->ddr_mode);
+ sd_set_timing(host, ios->timing);
host->vpclk = false;
host->double_clk = true;
goto out;
}
+out:
/* Stop toggle SD clock in idle */
err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
-out:
mutex_unlock(&pcr->pcr_mutex);
return err;
rtsx_pci_start_run(pcr);
- if (!host->ddr_mode)
- err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK);
+ /* Set initial TX phase */
+ switch (mmc->ios.timing) {
+ case MMC_TIMING_UHS_SDR104:
+ err = sd_change_phase(host, SDR104_TX_PHASE(pcr), false);
+ break;
+
+ case MMC_TIMING_UHS_SDR50:
+ err = sd_change_phase(host, SDR50_TX_PHASE(pcr), false);
+ break;
+
+ case MMC_TIMING_UHS_DDR50:
+ err = sd_change_phase(host, DDR50_TX_PHASE(pcr), false);
+ break;
+
+ default:
+ err = 0;
+ }
+ if (err)
+ goto out;
+
+ /* Tuning RX phase */
+ if ((mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
+ (mmc->ios.timing == MMC_TIMING_UHS_SDR50))
+ err = sd_tuning_rx(host, opcode);
+ else if (mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+ err = sd_change_phase(host, DDR50_RX_PHASE(pcr), true);
+
+out:
mutex_unlock(&pcr->pcr_mutex);
return err;
--- /dev/null
+/*
+ * Definitions for DA9063 MFD driver
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ * Krystian Garbaciak <krystian.garbaciak@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_DA9063_CORE_H__
+#define __MFD_DA9063_CORE_H__
+
+#include <linux/interrupt.h>
+#include <linux/mfd/da9063/registers.h>
+
+/* DA9063 modules */
+#define DA9063_DRVNAME_CORE "da9063-core"
+#define DA9063_DRVNAME_REGULATORS "da9063-regulators"
+#define DA9063_DRVNAME_LEDS "da9063-leds"
+#define DA9063_DRVNAME_WATCHDOG "da9063-watchdog"
+#define DA9063_DRVNAME_HWMON "da9063-hwmon"
+#define DA9063_DRVNAME_ONKEY "da9063-onkey"
+#define DA9063_DRVNAME_RTC "da9063-rtc"
+#define DA9063_DRVNAME_VIBRATION "da9063-vibration"
+
+enum da9063_models {
+ PMIC_DA9063 = 0x61,
+};
+
+/* Interrupts */
+enum da9063_irqs {
+ DA9063_IRQ_ONKEY = 0,
+ DA9063_IRQ_ALARM,
+ DA9063_IRQ_TICK,
+ DA9063_IRQ_ADC_RDY,
+ DA9063_IRQ_SEQ_RDY,
+ DA9063_IRQ_WAKE,
+ DA9063_IRQ_TEMP,
+ DA9063_IRQ_COMP_1V2,
+ DA9063_IRQ_LDO_LIM,
+ DA9063_IRQ_REG_UVOV,
+ DA9063_IRQ_VDD_MON,
+ DA9063_IRQ_WARN,
+ DA9063_IRQ_GPI0,
+ DA9063_IRQ_GPI1,
+ DA9063_IRQ_GPI2,
+ DA9063_IRQ_GPI3,
+ DA9063_IRQ_GPI4,
+ DA9063_IRQ_GPI5,
+ DA9063_IRQ_GPI6,
+ DA9063_IRQ_GPI7,
+ DA9063_IRQ_GPI8,
+ DA9063_IRQ_GPI9,
+ DA9063_IRQ_GPI10,
+ DA9063_IRQ_GPI11,
+ DA9063_IRQ_GPI12,
+ DA9063_IRQ_GPI13,
+ DA9063_IRQ_GPI14,
+ 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;
+ unsigned short revision;
+ unsigned int flags;
+
+ /* Control interface */
+ struct regmap *regmap;
+
+ /* Interrupts */
+ int chip_irq;
+ unsigned int irq_base;
+ struct regmap_irq_chip_data *regmap_irq;
+};
+
+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__ */
--- /dev/null
+/*
+ * Platform configuration options for DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_DA9063_PDATA_H__
+#define __MFD_DA9063_PDATA_H__
+
+#include <linux/regulator/machine.h>
+
+/*
+ * Regulator configuration
+ */
+/* DA9063 regulator IDs */
+enum {
+ /* BUCKs */
+ DA9063_ID_BCORE1,
+ DA9063_ID_BCORE2,
+ DA9063_ID_BPRO,
+ DA9063_ID_BMEM,
+ DA9063_ID_BIO,
+ DA9063_ID_BPERI,
+
+ /* BCORE1 and BCORE2 in merged mode */
+ DA9063_ID_BCORES_MERGED,
+ /* BMEM and BIO in merged mode */
+ DA9063_ID_BMEM_BIO_MERGED,
+ /* When two BUCKs are merged, they cannot be reused separately */
+
+ /* LDOs */
+ DA9063_ID_LDO1,
+ DA9063_ID_LDO2,
+ DA9063_ID_LDO3,
+ DA9063_ID_LDO4,
+ DA9063_ID_LDO5,
+ DA9063_ID_LDO6,
+ DA9063_ID_LDO7,
+ DA9063_ID_LDO8,
+ DA9063_ID_LDO9,
+ DA9063_ID_LDO10,
+ DA9063_ID_LDO11,
+};
+
+/* Regulators platform data */
+struct da9063_regulator_data {
+ int id;
+ struct regulator_init_data *initdata;
+};
+
+struct da9063_regulators_pdata {
+ unsigned n_regulators;
+ struct da9063_regulator_data *regulator_data;
+};
+
+
+/*
+ * RGB LED configuration
+ */
+/* LED IDs for flags in struct led_info. */
+enum {
+ DA9063_GPIO11_LED,
+ DA9063_GPIO14_LED,
+ DA9063_GPIO15_LED,
+
+ DA9063_LED_NUM
+};
+#define DA9063_LED_ID_MASK 0x3
+
+/* LED polarity for flags in struct led_info. */
+#define DA9063_LED_HIGH_LEVEL_ACTIVE 0x0
+#define DA9063_LED_LOW_LEVEL_ACTIVE 0x4
+
+
+/*
+ * General PMIC configuration
+ */
+/* HWMON ADC channels configuration */
+#define DA9063_FLG_FORCE_IN0_MANUAL_MODE 0x0010
+#define DA9063_FLG_FORCE_IN0_AUTO_MODE 0x0020
+#define DA9063_FLG_FORCE_IN1_MANUAL_MODE 0x0040
+#define DA9063_FLG_FORCE_IN1_AUTO_MODE 0x0080
+#define DA9063_FLG_FORCE_IN2_MANUAL_MODE 0x0100
+#define DA9063_FLG_FORCE_IN2_AUTO_MODE 0x0200
+#define DA9063_FLG_FORCE_IN3_MANUAL_MODE 0x0400
+#define DA9063_FLG_FORCE_IN3_AUTO_MODE 0x0800
+
+/* Disable register caching. */
+#define DA9063_FLG_NO_CACHE 0x0008
+
+struct da9063;
+
+/* DA9063 platform data */
+struct da9063_pdata {
+ int (*init)(struct da9063 *da9063);
+ int irq_base;
+ unsigned flags;
+ struct da9063_regulators_pdata *regulators_pdata;
+ struct led_platform_data *leds_pdata;
+};
+
+#endif /* __MFD_DA9063_PDATA_H__ */
--- /dev/null
+/*
+ * Registers definition for DA9063 modules
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ * Krystian Garbaciak <krystian.garbaciak@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _DA9063_REG_H
+#define _DA9063_REG_H
+
+#define DA9063_I2C_PAGE_SEL_SHIFT 1
+
+#define DA9063_EVENT_REG_NUM 4
+#define DA9210_EVENT_REG_NUM 2
+#define DA9063_EXT_EVENT_REG_NUM (DA9063_EVENT_REG_NUM + \
+ DA9210_EVENT_REG_NUM)
+
+/* Page selection I2C or SPI always in the begining of any page. */
+/* Page 0 : I2C access 0x000 - 0x0FF SPI access 0x000 - 0x07F */
+/* Page 1 : SPI access 0x080 - 0x0FF */
+/* Page 2 : I2C access 0x100 - 0x1FF SPI access 0x100 - 0x17F */
+/* Page 3 : SPI access 0x180 - 0x1FF */
+#define DA9063_REG_PAGE_CON 0x00
+
+/* System Control and Event Registers */
+#define DA9063_REG_STATUS_A 0x01
+#define DA9063_REG_STATUS_B 0x02
+#define DA9063_REG_STATUS_C 0x03
+#define DA9063_REG_STATUS_D 0x04
+#define DA9063_REG_FAULT_LOG 0x05
+#define DA9063_REG_EVENT_A 0x06
+#define DA9063_REG_EVENT_B 0x07
+#define DA9063_REG_EVENT_C 0x08
+#define DA9063_REG_EVENT_D 0x09
+#define DA9063_REG_IRQ_MASK_A 0x0A
+#define DA9063_REG_IRQ_MASK_B 0x0B
+#define DA9063_REG_IRQ_MASK_C 0x0C
+#define DA9063_REG_IRQ_MASK_D 0x0D
+#define DA9063_REG_CONTROL_A 0x0E
+#define DA9063_REG_CONTROL_B 0x0F
+#define DA9063_REG_CONTROL_C 0x10
+#define DA9063_REG_CONTROL_D 0x11
+#define DA9063_REG_CONTROL_E 0x12
+#define DA9063_REG_CONTROL_F 0x13
+#define DA9063_REG_PD_DIS 0x14
+
+/* GPIO Control Registers */
+#define DA9063_REG_GPIO_0_1 0x15
+#define DA9063_REG_GPIO_2_3 0x16
+#define DA9063_REG_GPIO_4_5 0x17
+#define DA9063_REG_GPIO_6_7 0x18
+#define DA9063_REG_GPIO_8_9 0x19
+#define DA9063_REG_GPIO_10_11 0x1A
+#define DA9063_REG_GPIO_12_13 0x1B
+#define DA9063_REG_GPIO_14_15 0x1C
+#define DA9063_REG_GPIO_MODE_0_7 0x1D
+#define DA9063_REG_GPIO_MODE_8_15 0x1E
+#define DA9063_REG_GPIO_SWITCH_CONT 0x1F
+
+/* Regulator Control Registers */
+#define DA9063_REG_BCORE2_CONT 0x20
+#define DA9063_REG_BCORE1_CONT 0x21
+#define DA9063_REG_BPRO_CONT 0x22
+#define DA9063_REG_BMEM_CONT 0x23
+#define DA9063_REG_BIO_CONT 0x24
+#define DA9063_REG_BPERI_CONT 0x25
+#define DA9063_REG_LDO1_CONT 0x26
+#define DA9063_REG_LDO2_CONT 0x27
+#define DA9063_REG_LDO3_CONT 0x28
+#define DA9063_REG_LDO4_CONT 0x29
+#define DA9063_REG_LDO5_CONT 0x2A
+#define DA9063_REG_LDO6_CONT 0x2B
+#define DA9063_REG_LDO7_CONT 0x2C
+#define DA9063_REG_LDO8_CONT 0x2D
+#define DA9063_REG_LDO9_CONT 0x2E
+#define DA9063_REG_LDO10_CONT 0x2F
+#define DA9063_REG_LDO11_CONT 0x30
+#define DA9063_REG_VIB 0x31
+#define DA9063_REG_DVC_1 0x32
+#define DA9063_REG_DVC_2 0x33
+
+/* GP-ADC Control Registers */
+#define DA9063_REG_ADC_MAN 0x34
+#define DA9063_REG_ADC_CONT 0x35
+#define DA9063_REG_VSYS_MON 0x36
+#define DA9063_REG_ADC_RES_L 0x37
+#define DA9063_REG_ADC_RES_H 0x38
+#define DA9063_REG_VSYS_RES 0x39
+#define DA9063_REG_ADCIN1_RES 0x3A
+#define DA9063_REG_ADCIN2_RES 0x3B
+#define DA9063_REG_ADCIN3_RES 0x3C
+#define DA9063_REG_MON1_RES 0x3D
+#define DA9063_REG_MON2_RES 0x3E
+#define DA9063_REG_MON3_RES 0x3F
+
+/* RTC Calendar and Alarm Registers */
+#define DA9063_REG_COUNT_S 0x40
+#define DA9063_REG_COUNT_MI 0x41
+#define DA9063_REG_COUNT_H 0x42
+#define DA9063_REG_COUNT_D 0x43
+#define DA9063_REG_COUNT_MO 0x44
+#define DA9063_REG_COUNT_Y 0x45
+#define DA9063_REG_ALARM_MI 0x46
+#define DA9063_REG_ALARM_H 0x47
+#define DA9063_REG_ALARM_D 0x48
+#define DA9063_REG_ALARM_MO 0x49
+#define DA9063_REG_ALARM_Y 0x4A
+#define DA9063_REG_SECOND_A 0x4B
+#define DA9063_REG_SECOND_B 0x4C
+#define DA9063_REG_SECOND_C 0x4D
+#define DA9063_REG_SECOND_D 0x4E
+
+/* Sequencer Control Registers */
+#define DA9063_REG_SEQ 0x81
+#define DA9063_REG_SEQ_TIMER 0x82
+#define DA9063_REG_ID_2_1 0x83
+#define DA9063_REG_ID_4_3 0x84
+#define DA9063_REG_ID_6_5 0x85
+#define DA9063_REG_ID_8_7 0x86
+#define DA9063_REG_ID_10_9 0x87
+#define DA9063_REG_ID_12_11 0x88
+#define DA9063_REG_ID_14_13 0x89
+#define DA9063_REG_ID_16_15 0x8A
+#define DA9063_REG_ID_18_17 0x8B
+#define DA9063_REG_ID_20_19 0x8C
+#define DA9063_REG_ID_22_21 0x8D
+#define DA9063_REG_ID_24_23 0x8E
+#define DA9063_REG_ID_26_25 0x8F
+#define DA9063_REG_ID_28_27 0x90
+#define DA9063_REG_ID_30_29 0x91
+#define DA9063_REG_ID_32_31 0x92
+#define DA9063_REG_SEQ_A 0x95
+#define DA9063_REG_SEQ_B 0x96
+#define DA9063_REG_WAIT 0x97
+#define DA9063_REG_EN_32K 0x98
+#define DA9063_REG_RESET 0x99
+
+/* Regulator Setting Registers */
+#define DA9063_REG_BUCK_ILIM_A 0x9A
+#define DA9063_REG_BUCK_ILIM_B 0x9B
+#define DA9063_REG_BUCK_ILIM_C 0x9C
+#define DA9063_REG_BCORE2_CFG 0x9D
+#define DA9063_REG_BCORE1_CFG 0x9E
+#define DA9063_REG_BPRO_CFG 0x9F
+#define DA9063_REG_BIO_CFG 0xA0
+#define DA9063_REG_BMEM_CFG 0xA1
+#define DA9063_REG_BPERI_CFG 0xA2
+#define DA9063_REG_VBCORE2_A 0xA3
+#define DA9063_REG_VBCORE1_A 0xA4
+#define DA9063_REG_VBPRO_A 0xA5
+#define DA9063_REG_VBMEM_A 0xA6
+#define DA9063_REG_VBIO_A 0xA7
+#define DA9063_REG_VBPERI_A 0xA8
+#define DA9063_REG_VLDO1_A 0xA9
+#define DA9063_REG_VLDO2_A 0xAA
+#define DA9063_REG_VLDO3_A 0xAB
+#define DA9063_REG_VLDO4_A 0xAC
+#define DA9063_REG_VLDO5_A 0xAD
+#define DA9063_REG_VLDO6_A 0xAE
+#define DA9063_REG_VLDO7_A 0xAF
+#define DA9063_REG_VLDO8_A 0xB0
+#define DA9063_REG_VLDO9_A 0xB1
+#define DA9063_REG_VLDO10_A 0xB2
+#define DA9063_REG_VLDO11_A 0xB3
+#define DA9063_REG_VBCORE2_B 0xB4
+#define DA9063_REG_VBCORE1_B 0xB5
+#define DA9063_REG_VBPRO_B 0xB6
+#define DA9063_REG_VBMEM_B 0xB7
+#define DA9063_REG_VBIO_B 0xB8
+#define DA9063_REG_VBPERI_B 0xB9
+#define DA9063_REG_VLDO1_B 0xBA
+#define DA9063_REG_VLDO2_B 0xBB
+#define DA9063_REG_VLDO3_B 0xBC
+#define DA9063_REG_VLDO4_B 0xBD
+#define DA9063_REG_VLDO5_B 0xBE
+#define DA9063_REG_VLDO6_B 0xBF
+#define DA9063_REG_VLDO7_B 0xC0
+#define DA9063_REG_VLDO8_B 0xC1
+#define DA9063_REG_VLDO9_B 0xC2
+#define DA9063_REG_VLDO10_B 0xC3
+#define DA9063_REG_VLDO11_B 0xC4
+
+/* Backup Battery Charger Control Register */
+#define DA9063_REG_BBAT_CONT 0xC5
+
+/* GPIO PWM (LED) */
+#define DA9063_REG_GPO11_LED 0xC6
+#define DA9063_REG_GPO14_LED 0xC7
+#define DA9063_REG_GPO15_LED 0xC8
+
+/* GP-ADC Threshold Registers */
+#define DA9063_REG_ADC_CFG 0xC9
+#define DA9063_REG_AUTO1_HIGH 0xCA
+#define DA9063_REG_AUTO1_LOW 0xCB
+#define DA9063_REG_AUTO2_HIGH 0xCC
+#define DA9063_REG_AUTO2_LOW 0xCD
+#define DA9063_REG_AUTO3_HIGH 0xCE
+#define DA9063_REG_AUTO3_LOW 0xCF
+
+/* DA9063 Configuration registers */
+/* OTP */
+#define DA9063_REG_OPT_COUNT 0x101
+#define DA9063_REG_OPT_ADDR 0x102
+#define DA9063_REG_OPT_DATA 0x103
+
+/* Customer Trim and Configuration */
+#define DA9063_REG_T_OFFSET 0x104
+#define DA9063_REG_INTERFACE 0x105
+#define DA9063_REG_CONFIG_A 0x106
+#define DA9063_REG_CONFIG_B 0x107
+#define DA9063_REG_CONFIG_C 0x108
+#define DA9063_REG_CONFIG_D 0x109
+#define DA9063_REG_CONFIG_E 0x10A
+#define DA9063_REG_CONFIG_F 0x10B
+#define DA9063_REG_CONFIG_G 0x10C
+#define DA9063_REG_CONFIG_H 0x10D
+#define DA9063_REG_CONFIG_I 0x10E
+#define DA9063_REG_CONFIG_J 0x10F
+#define DA9063_REG_CONFIG_K 0x110
+#define DA9063_REG_CONFIG_L 0x111
+#define DA9063_REG_MON_REG_1 0x112
+#define DA9063_REG_MON_REG_2 0x113
+#define DA9063_REG_MON_REG_3 0x114
+#define DA9063_REG_MON_REG_4 0x115
+#define DA9063_REG_MON_REG_5 0x116
+#define DA9063_REG_MON_REG_6 0x117
+#define DA9063_REG_TRIM_CLDR 0x118
+
+/* General Purpose Registers */
+#define DA9063_REG_GP_ID_0 0x119
+#define DA9063_REG_GP_ID_1 0x11A
+#define DA9063_REG_GP_ID_2 0x11B
+#define DA9063_REG_GP_ID_3 0x11C
+#define DA9063_REG_GP_ID_4 0x11D
+#define DA9063_REG_GP_ID_5 0x11E
+#define DA9063_REG_GP_ID_6 0x11F
+#define DA9063_REG_GP_ID_7 0x120
+#define DA9063_REG_GP_ID_8 0x121
+#define DA9063_REG_GP_ID_9 0x122
+#define DA9063_REG_GP_ID_10 0x123
+#define DA9063_REG_GP_ID_11 0x124
+#define DA9063_REG_GP_ID_12 0x125
+#define DA9063_REG_GP_ID_13 0x126
+#define DA9063_REG_GP_ID_14 0x127
+#define DA9063_REG_GP_ID_15 0x128
+#define DA9063_REG_GP_ID_16 0x129
+#define DA9063_REG_GP_ID_17 0x12A
+#define DA9063_REG_GP_ID_18 0x12B
+#define DA9063_REG_GP_ID_19 0x12C
+
+/* Chip ID and variant */
+#define DA9063_REG_CHIP_ID 0x181
+#define DA9063_REG_CHIP_VARIANT 0x182
+
+/*
+ * PMIC registers bits
+ */
+/* DA9063_REG_PAGE_CON (addr=0x00) */
+#define DA9063_PEG_PAGE_SHIFT 0
+#define DA9063_REG_PAGE_MASK 0x07
+#define DA9063_REG_PAGE0 0x00
+#define DA9063_REG_PAGE2 0x02
+#define DA9063_PAGE_WRITE_MODE 0x00
+#define DA9063_REPEAT_WRITE_MODE 0x40
+#define DA9063_PAGE_REVERT 0x80
+
+/* DA9063_REG_STATUS_A (addr=0x01) */
+#define DA9063_NONKEY 0x01
+#define DA9063_WAKE 0x02
+#define DA9063_DVC_BUSY 0x04
+#define DA9063_COMP_1V2 0x08
+
+/* DA9063_REG_STATUS_B (addr=0x02) */
+#define DA9063_GPI0 0x01
+#define DA9063_GPI1 0x02
+#define DA9063_GPI2 0x04
+#define DA9063_GPI3 0x08
+#define DA9063_GPI4 0x10
+#define DA9063_GPI5 0x20
+#define DA9063_GPI6 0x40
+#define DA9063_GPI7 0x80
+
+/* DA9063_REG_STATUS_C (addr=0x03) */
+#define DA9063_GPI8 0x01
+#define DA9063_GPI9 0x02
+#define DA9063_GPI10 0x04
+#define DA9063_GPI11 0x08
+#define DA9063_GPI12 0x10
+#define DA9063_GPI13 0x20
+#define DA9063_GPI14 0x40
+#define DA9063_GPI15 0x80
+
+/* DA9063_REG_STATUS_D (addr=0x04) */
+#define DA9063_LDO3_LIM 0x08
+#define DA9063_LDO4_LIM 0x10
+#define DA9063_LDO7_LIM 0x20
+#define DA9063_LDO8_LIM 0x40
+#define DA9063_LDO11_LIM 0x80
+
+/* DA9063_REG_FAULT_LOG (addr=0x05) */
+#define DA9063_TWD_ERROR 0x01
+#define DA9063_POR 0x02
+#define DA9063_VDD_FAULT 0x04
+#define DA9063_VDD_START 0x08
+#define DA9063_TEMP_CRIT 0x10
+#define DA9063_KEY_RESET 0x20
+#define DA9063_NSHUTDOWN 0x40
+#define DA9063_WAIT_SHUT 0x80
+
+/* DA9063_REG_EVENT_A (addr=0x06) */
+#define DA9063_E_NONKEY 0x01
+#define DA9063_E_ALARM 0x02
+#define DA9063_E_TICK 0x04
+#define DA9063_E_ADC_RDY 0x08
+#define DA9063_E_SEQ_RDY 0x10
+#define DA9063_EVENTS_B 0x20
+#define DA9063_EVENTS_C 0x40
+#define DA9063_EVENTS_D 0x80
+
+/* DA9063_REG_EVENT_B (addr=0x07) */
+#define DA9063_E_WAKE 0x01
+#define DA9063_E_TEMP 0x02
+#define DA9063_E_COMP_1V2 0x04
+#define DA9063_E_LDO_LIM 0x08
+#define DA9063_E_REG_UVOV 0x10
+#define DA9063_E_DVC_RDY 0x20
+#define DA9063_E_VDD_MON 0x40
+#define DA9063_E_VDD_WARN 0x80
+
+/* DA9063_REG_EVENT_C (addr=0x08) */
+#define DA9063_E_GPI0 0x01
+#define DA9063_E_GPI1 0x02
+#define DA9063_E_GPI2 0x04
+#define DA9063_E_GPI3 0x08
+#define DA9063_E_GPI4 0x10
+#define DA9063_E_GPI5 0x20
+#define DA9063_E_GPI6 0x40
+#define DA9063_E_GPI7 0x80
+
+/* DA9063_REG_EVENT_D (addr=0x09) */
+#define DA9063_E_GPI8 0x01
+#define DA9063_E_GPI9 0x02
+#define DA9063_E_GPI10 0x04
+#define DA9063_E_GPI11 0x08
+#define DA9063_E_GPI12 0x10
+#define DA9063_E_GPI13 0x20
+#define DA9063_E_GPI14 0x40
+#define DA9063_E_GPI15 0x80
+
+/* DA9063_REG_IRQ_MASK_A (addr=0x0A) */
+#define DA9063_M_ONKEY 0x01
+#define DA9063_M_ALARM 0x02
+#define DA9063_M_TICK 0x04
+#define DA9063_M_ADC_RDY 0x08
+#define DA9063_M_SEQ_RDY 0x10
+
+/* DA9063_REG_IRQ_MASK_B (addr=0x0B) */
+#define DA9063_M_WAKE 0x01
+#define DA9063_M_TEMP 0x02
+#define DA9063_M_COMP_1V2 0x04
+#define DA9063_M_LDO_LIM 0x08
+#define DA9063_M_UVOV 0x10
+#define DA9063_M_DVC_RDY 0x20
+#define DA9063_M_VDD_MON 0x40
+#define DA9063_M_VDD_WARN 0x80
+
+/* DA9063_REG_IRQ_MASK_C (addr=0x0C) */
+#define DA9063_M_GPI0 0x01
+#define DA9063_M_GPI1 0x02
+#define DA9063_M_GPI2 0x04
+#define DA9063_M_GPI3 0x08
+#define DA9063_M_GPI4 0x10
+#define DA9063_M_GPI5 0x20
+#define DA9063_M_GPI6 0x40
+#define DA9063_M_GPI7 0x80
+
+/* DA9063_REG_IRQ_MASK_D (addr=0x0D) */
+#define DA9063_M_GPI8 0x01
+#define DA9063_M_GPI9 0x02
+#define DA9063_M_GPI10 0x04
+#define DA9063_M_GPI11 0x08
+#define DA9063_M_GPI12 0x10
+#define DA9063_M_GPI13 0x20
+#define DA9063_M_GPI14 0x40
+#define DA9063_M_GPI15 0x80
+
+/* DA9063_REG_CONTROL_A (addr=0x0E) */
+#define DA9063_SYSTEM_EN 0x01
+#define DA9063_POWER_EN 0x02
+#define DA9063_POWER1_EN 0x04
+#define DA9063_STANDBY 0x08
+#define DA9063_M_SYSTEM_EN 0x10
+#define DA9063_M_POWER_EN 0x20
+#define DA9063_M_POWER1_EN 0x40
+#define DA9063_CP_EN 0x80
+
+/* DA9063_REG_CONTROL_B (addr=0x0F) */
+#define DA9063_CHG_SEL 0x01
+#define DA9063_WATCHDOG_PD 0x02
+#define DA9063_NRES_MODE 0x08
+#define DA9063_NONKEY_LOCK 0x10
+
+/* DA9063_REG_CONTROL_C (addr=0x10) */
+#define DA9063_DEBOUNCING_MASK 0x07
+#define DA9063_DEBOUNCING_OFF 0x0
+#define DA9063_DEBOUNCING_0MS1 0x1
+#define DA9063_DEBOUNCING_1MS 0x2
+#define DA9063_DEBOUNCING_10MS24 0x3
+#define DA9063_DEBOUNCING_51MS2 0x4
+#define DA9063_DEBOUNCING_256MS 0x5
+#define DA9063_DEBOUNCING_512MS 0x6
+#define DA9063_DEBOUNCING_1024MS 0x7
+
+#define DA9063_AUTO_BOOT 0x08
+#define DA9063_OTPREAD_EN 0x10
+#define DA9063_SLEW_RATE_MASK 0x60
+#define DA9063_SLEW_RATE_4US 0x00
+#define DA9063_SLEW_RATE_3US 0x20
+#define DA9063_SLEW_RATE_1US 0x40
+#define DA9063_SLEW_RATE_0US5 0x60
+#define DA9063_DEF_SUPPLY 0x80
+
+/* DA9063_REG_CONTROL_D (addr=0x11) */
+#define DA9063_TWDSCALE_MASK 0x07
+#define DA9063_BLINK_FRQ_MASK 0x38
+#define DA9063_BLINK_FRQ_OFF 0x00
+#define DA9063_BLINK_FRQ_1S0 0x08
+#define DA9063_BLINK_FRQ_2S0 0x10
+#define DA9063_BLINK_FRQ_4S0 0x18
+#define DA9063_BLINK_FRQ_0S18 0x20
+#define DA9063_BLINK_FRQ_2S0_VDD 0x28
+#define DA9063_BLINK_FRQ_4S0_VDD 0x30
+#define DA9063_BLINK_FRQ_0S18_VDD 0x38
+
+#define DA9063_BLINK_DUR_MASK 0xC0
+#define DA9063_BLINK_DUR_10MS 0x00
+#define DA9063_BLINK_DUR_20MS 0x40
+#define DA9063_BLINK_DUR_40MS 0x80
+#define DA9063_BLINK_DUR_20MSDBL 0xC0
+
+/* DA9063_REG_CONTROL_E (addr=0x12) */
+#define DA9063_RTC_MODE_PD 0x01
+#define DA9063_RTC_MODE_SD 0x02
+#define DA9063_RTC_EN 0x04
+#define DA9063_ECO_MODE 0x08
+#define DA9063_PM_FB1_PIN 0x10
+#define DA9063_PM_FB2_PIN 0x20
+#define DA9063_PM_FB3_PIN 0x40
+#define DA9063_V_LOCK 0x80
+
+/* DA9063_REG_CONTROL_F (addr=0x13) */
+#define DA9063_WATCHDOG 0x01
+#define DA9063_SHUTDOWN 0x02
+#define DA9063_WAKE_UP 0x04
+
+/* DA9063_REG_PD_DIS (addr=0x14) */
+#define DA9063_GPI_DIS 0x01
+#define DA9063_GPADC_PAUSE 0x02
+#define DA9063_PMIF_DIS 0x04
+#define DA9063_HS2WIRE_DIS 0x08
+#define DA9063_BBAT_DIS 0x20
+#define DA9063_OUT_32K_PAUSE 0x40
+#define DA9063_PMCONT_DIS 0x80
+
+/* DA9063_REG_GPIO_0_1 (addr=0x15) */
+#define DA9063_GPIO0_PIN_MASK 0x03
+#define DA9063_GPIO0_PIN_ADCIN1 0x00
+#define DA9063_GPIO0_PIN_GPI 0x01
+#define DA9063_GPIO0_PIN_GPO_OD 0x02
+#define DA9063_GPIO0_PIN_GPO 0x03
+#define DA9063_GPIO0_TYPE 0x04
+#define DA9063_GPIO0_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO0_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO0_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO0_NO_WAKEUP 0x08
+#define DA9063_GPIO1_PIN_MASK 0x30
+#define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00
+#define DA9063_GPIO1_PIN_GPI 0x10
+#define DA9063_GPIO1_PIN_GPO_OD 0x20
+#define DA9063_GPIO1_PIN_GPO 0x30
+#define DA9063_GPIO1_TYPE 0x40
+#define DA9063_GPIO1_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO1_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO1_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO1_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO1_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_2_3 (addr=0x16) */
+#define DA9063_GPIO2_PIN_MASK 0x03
+#define DA9063_GPIO2_PIN_ADCIN3 0x00
+#define DA9063_GPIO2_PIN_GPI 0x01
+#define DA9063_GPIO2_PIN_GPO_PSS 0x02
+#define DA9063_GPIO2_PIN_GPO 0x03
+#define DA9063_GPIO2_TYPE 0x04
+#define DA9063_GPIO2_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO2_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO2_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO2_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO2_NO_WAKEUP 0x08
+#define DA9063_GPIO3_PIN_MASK 0x30
+#define DA9063_GPIO3_PIN_CORE_SW_G 0x00
+#define DA9063_GPIO3_PIN_GPI 0x10
+#define DA9063_GPIO3_PIN_GPO_OD 0x20
+#define DA9063_GPIO3_PIN_GPO 0x30
+#define DA9063_GPIO3_TYPE 0x40
+#define DA9063_GPIO3_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO3_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO3_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO3_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO3_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_4_5 (addr=0x17) */
+#define DA9063_GPIO4_PIN_MASK 0x03
+#define DA9063_GPIO4_PIN_CORE_SW_S 0x00
+#define DA9063_GPIO4_PIN_GPI 0x01
+#define DA9063_GPIO4_PIN_GPO_OD 0x02
+#define DA9063_GPIO4_PIN_GPO 0x03
+#define DA9063_GPIO4_TYPE 0x04
+#define DA9063_GPIO4_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO4_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO4_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO4_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO4_NO_WAKEUP 0x08
+#define DA9063_GPIO5_PIN_MASK 0x30
+#define DA9063_GPIO5_PIN_PERI_SW_G 0x00
+#define DA9063_GPIO5_PIN_GPI 0x10
+#define DA9063_GPIO5_PIN_GPO_OD 0x20
+#define DA9063_GPIO5_PIN_GPO 0x30
+#define DA9063_GPIO5_TYPE 0x40
+#define DA9063_GPIO5_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO5_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO5_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO5_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO5_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_6_7 (addr=0x18) */
+#define DA9063_GPIO6_PIN_MASK 0x03
+#define DA9063_GPIO6_PIN_PERI_SW_S 0x00
+#define DA9063_GPIO6_PIN_GPI 0x01
+#define DA9063_GPIO6_PIN_GPO_OD 0x02
+#define DA9063_GPIO6_PIN_GPO 0x03
+#define DA9063_GPIO6_TYPE 0x04
+#define DA9063_GPIO6_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO6_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO6_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO6_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO6_NO_WAKEUP 0x08
+#define DA9063_GPIO7_PIN_MASK 0x30
+#define DA9063_GPIO7_PIN_GPI 0x10
+#define DA9063_GPIO7_PIN_GPO_PSS 0x20
+#define DA9063_GPIO7_PIN_GPO 0x30
+#define DA9063_GPIO7_TYPE 0x40
+#define DA9063_GPIO7_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO7_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO7_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO7_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO7_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_8_9 (addr=0x19) */
+#define DA9063_GPIO8_PIN_MASK 0x03
+#define DA9063_GPIO8_PIN_GPI_SYS_EN 0x00
+#define DA9063_GPIO8_PIN_GPI 0x01
+#define DA9063_GPIO8_PIN_GPO_PSS 0x02
+#define DA9063_GPIO8_PIN_GPO 0x03
+#define DA9063_GPIO8_TYPE 0x04
+#define DA9063_GPIO8_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO8_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO8_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO8_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO8_NO_WAKEUP 0x08
+#define DA9063_GPIO9_PIN_MASK 0x30
+#define DA9063_GPIO9_PIN_GPI_PWR_EN 0x00
+#define DA9063_GPIO9_PIN_GPI 0x10
+#define DA9063_GPIO9_PIN_GPO_PSS 0x20
+#define DA9063_GPIO9_PIN_GPO 0x30
+#define DA9063_GPIO9_TYPE 0x40
+#define DA9063_GPIO9_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO9_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO9_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO9_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO9_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_10_11 (addr=0x1A) */
+#define DA9063_GPIO10_PIN_MASK 0x03
+#define DA9063_GPIO10_PIN_GPI_PWR1_EN 0x00
+#define DA9063_GPIO10_PIN_GPI 0x01
+#define DA9063_GPIO10_PIN_GPO_OD 0x02
+#define DA9063_GPIO10_PIN_GPO 0x03
+#define DA9063_GPIO10_TYPE 0x04
+#define DA9063_GPIO10_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO10_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO10_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO10_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO10_NO_WAKEUP 0x08
+#define DA9063_GPIO11_PIN_MASK 0x30
+#define DA9063_GPIO11_PIN_GPO_OD 0x00
+#define DA9063_GPIO11_PIN_GPI 0x10
+#define DA9063_GPIO11_PIN_GPO_PSS 0x20
+#define DA9063_GPIO11_PIN_GPO 0x30
+#define DA9063_GPIO11_TYPE 0x40
+#define DA9063_GPIO11_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO11_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO11_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO11_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO11_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_12_13 (addr=0x1B) */
+#define DA9063_GPIO12_PIN_MASK 0x03
+#define DA9063_GPIO12_PIN_NVDDFLT_OUT 0x00
+#define DA9063_GPIO12_PIN_GPI 0x01
+#define DA9063_GPIO12_PIN_VSYSMON_OUT 0x02
+#define DA9063_GPIO12_PIN_GPO 0x03
+#define DA9063_GPIO12_TYPE 0x04
+#define DA9063_GPIO12_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO12_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO12_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO12_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO12_NO_WAKEUP 0x08
+#define DA9063_GPIO13_PIN_MASK 0x30
+#define DA9063_GPIO13_PIN_GPFB1_OUT 0x00
+#define DA9063_GPIO13_PIN_GPI 0x10
+#define DA9063_GPIO13_PIN_GPFB1_OUTOD 0x20
+#define DA9063_GPIO13_PIN_GPO 0x30
+#define DA9063_GPIO13_TYPE 0x40
+#define DA9063_GPIO13_TYPE_GPFB1_OUT 0x00
+#define DA9063_GPIO13_TYPE_GPI 0x00
+#define DA9063_GPIO13_TYPE_GPFB1_OUTOD 0x04
+#define DA9063_GPIO13_TYPE_GPO 0x04
+#define DA9063_GPIO13_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_14_15 (addr=0x1C) */
+#define DA9063_GPIO14_PIN_MASK 0x03
+#define DA9063_GPIO14_PIN_GPO_OD 0x00
+#define DA9063_GPIO14_PIN_GPI 0x01
+#define DA9063_GPIO14_PIN_HS2DATA 0x02
+#define DA9063_GPIO14_PIN_GPO 0x03
+#define DA9063_GPIO14_TYPE 0x04
+#define DA9063_GPIO14_TYPE_GPI_ACT_LOW 0x00
+#define DA9063_GPIO14_TYPE_GPO_VDD_IO1 0x00
+#define DA9063_GPIO14_TYPE_GPI_ACT_HIGH 0x04
+#define DA9063_GPIO14_TYPE_GPO_VDD_IO2 0x04
+#define DA9063_GPIO14_NO_WAKEUP 0x08
+#define DA9063_GPIO15_PIN_MASK 0x30
+#define DA9063_GPIO15_PIN_GPO_OD 0x00
+#define DA9063_GPIO15_PIN_GPI 0x10
+#define DA9063_GPIO15_PIN_GPO 0x30
+#define DA9063_GPIO15_TYPE 0x40
+#define DA9063_GPIO15_TYPE_GPFB1_OUT 0x00
+#define DA9063_GPIO15_TYPE_GPI 0x00
+#define DA9063_GPIO15_TYPE_GPFB1_OUTOD 0x04
+#define DA9063_GPIO15_TYPE_GPO 0x04
+#define DA9063_GPIO15_NO_WAKEUP 0x80
+
+/* DA9063_REG_GPIO_MODE_0_7 (addr=0x1D) */
+#define DA9063_GPIO0_MODE 0x01
+#define DA9063_GPIO1_MODE 0x02
+#define DA9063_GPIO2_MODE 0x04
+#define DA9063_GPIO3_MODE 0x08
+#define DA9063_GPIO4_MODE 0x10
+#define DA9063_GPIO5_MODE 0x20
+#define DA9063_GPIO6_MODE 0x40
+#define DA9063_GPIO7_MODE 0x80
+
+/* DA9063_REG_GPIO_MODE_8_15 (addr=0x1E) */
+#define DA9063_GPIO8_MODE 0x01
+#define DA9063_GPIO9_MODE 0x02
+#define DA9063_GPIO10_MODE 0x04
+#define DA9063_GPIO11_MODE 0x08
+#define DA9063_GPIO11_MODE_LED_ACT_HIGH 0x00
+#define DA9063_GPIO11_MODE_LED_ACT_LOW 0x08
+#define DA9063_GPIO12_MODE 0x10
+#define DA9063_GPIO13_MODE 0x20
+#define DA9063_GPIO14_MODE 0x40
+#define DA9063_GPIO14_MODE_LED_ACT_HIGH 0x00
+#define DA9063_GPIO14_MODE_LED_ACT_LOW 0x40
+#define DA9063_GPIO15_MODE 0x80
+#define DA9063_GPIO15_MODE_LED_ACT_HIGH 0x00
+#define DA9063_GPIO15_MODE_LED_ACT_LOW 0x80
+
+/* DA9063_REG_SWITCH_CONT (addr=0x1F) */
+#define DA9063_CORE_SW_GPI_MASK 0x03
+#define DA9063_CORE_SW_GPI_OFF 0x00
+#define DA9063_CORE_SW_GPI_GPIO1 0x01
+#define DA9063_CORE_SW_GPI_GPIO2 0x02
+#define DA9063_CORE_SW_GPI_GPIO13 0x03
+#define DA9063_PERI_SW_GPI_MASK 0x0C
+#define DA9063_PERI_SW_GPI_OFF 0x00
+#define DA9063_PERI_SW_GPI_GPIO1 0x04
+#define DA9063_PERI_SW_GPI_GPIO2 0x08
+#define DA9063_PERI_SW_GPI_GPIO13 0x0C
+#define DA9063_SWITCH_SR_MASK 0x30
+#define DA9063_SWITCH_SR_1MV 0x00
+#define DA9063_SWITCH_SR_5MV 0x10
+#define DA9063_SWITCH_SR_10MV 0x20
+#define DA9063_SWITCH_SR_50MV 0x30
+#define DA9063_SWITCH_SR_DIS 0x40
+#define DA9063_CP_EN_MODE 0x80
+
+/* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */
+#define DA9063_BUCK_EN 0x01
+#define DA9063_BUCK_GPI_MASK 0x06
+#define DA9063_BUCK_GPI_OFF 0x00
+#define DA9063_BUCK_GPI_GPIO1 0x02
+#define DA9063_BUCK_GPI_GPIO2 0x04
+#define DA9063_BUCK_GPI_GPIO13 0x06
+#define DA9063_BUCK_CONF 0x08
+#define DA9063_VBUCK_GPI_MASK 0x60
+#define DA9063_VBUCK_GPI_OFF 0x00
+#define DA9063_VBUCK_GPI_GPIO1 0x20
+#define DA9063_VBUCK_GPI_GPIO2 0x40
+#define DA9063_VBUCK_GPI_GPIO13 0x60
+
+/* DA9063_REG_BCORE1_CONT specific bits (addr=0x21) */
+#define DA9063_CORE_SW_EN 0x10
+#define DA9063_CORE_SW_CONF 0x80
+
+/* DA9063_REG_BPERI_CONT specific bits (addr=0x25) */
+#define DA9063_PERI_SW_EN 0x10
+#define DA9063_PERI_SW_CONF 0x80
+
+/* DA9063_REG_LDOx_CONT common bits (addr=0x26-0x30) */
+#define DA9063_LDO_EN 0x01
+#define DA9063_LDO_GPI_MASK 0x06
+#define DA9063_LDO_GPI_OFF 0x00
+#define DA9063_LDO_GPI_GPIO1 0x02
+#define DA9063_LDO_GPI_GPIO2 0x04
+#define DA9063_LDO_GPI_GPIO13 0x06
+#define DA9063_LDO_PD_DIS 0x08
+#define DA9063_VLDO_GPI_MASK 0x60
+#define DA9063_VLDO_GPI_OFF 0x00
+#define DA9063_VLDO_GPI_GPIO1 0x20
+#define DA9063_VLDO_GPI_GPIO2 0x40
+#define DA9063_VLDO_GPI_GPIO13 0x60
+#define DA9063_LDO_CONF 0x80
+
+/* DA9063_REG_LDO5_CONT specific bits (addr=0x2A) */
+#define DA9063_VLDO5_SEL 0x10
+
+/* DA9063_REG_LDO6_CONT specific bits (addr=0x2B) */
+#define DA9063_VLDO6_SEL 0x10
+
+/* DA9063_REG_LDO7_CONT specific bits (addr=0x2C) */
+#define DA9063_VLDO7_SEL 0x10
+
+/* DA9063_REG_LDO8_CONT specific bits (addr=0x2D) */
+#define DA9063_VLDO8_SEL 0x10
+
+/* DA9063_REG_LDO9_CONT specific bits (addr=0x2E) */
+#define DA9063_VLDO9_SEL 0x10
+
+/* DA9063_REG_LDO10_CONT specific bits (addr=0x2F) */
+#define DA9063_VLDO10_SEL 0x10
+
+/* DA9063_REG_LDO11_CONT specific bits (addr=0x30) */
+#define DA9063_VLDO11_SEL 0x10
+
+/* DA9063_REG_VIB (addr=0x31) */
+#define DA9063_VIB_SET_MASK 0x3F
+#define DA9063_VIB_SET_OFF 0
+#define DA9063_VIB_SET_MAX 0x3F
+
+/* DA9063_REG_DVC_1 (addr=0x32) */
+#define DA9063_VBCORE1_SEL 0x01
+#define DA9063_VBCORE2_SEL 0x02
+#define DA9063_VBPRO_SEL 0x04
+#define DA9063_VBMEM_SEL 0x08
+#define DA9063_VBPERI_SEL 0x10
+#define DA9063_VLDO1_SEL 0x20
+#define DA9063_VLDO2_SEL 0x40
+#define DA9063_VLDO3_SEL 0x80
+
+/* DA9063_REG_DVC_2 (addr=0x33) */
+#define DA9063_VBIO_SEL 0x01
+#define DA9063_VLDO4_SEL 0x80
+
+/* DA9063_REG_ADC_MAN (addr=0x34) */
+#define DA9063_ADC_MUX_MASK 0x0F
+#define DA9063_ADC_MUX_VSYS 0x00
+#define DA9063_ADC_MUX_ADCIN1 0x01
+#define DA9063_ADC_MUX_ADCIN2 0x02
+#define DA9063_ADC_MUX_ADCIN3 0x03
+#define DA9063_ADC_MUX_T_SENSE 0x04
+#define DA9063_ADC_MUX_VBBAT 0x05
+#define DA9063_ADC_MUX_LDO_G1 0x08
+#define DA9063_ADC_MUX_LDO_G2 0x09
+#define DA9063_ADC_MUX_LDO_G3 0x0A
+#define DA9063_ADC_MAN 0x10
+#define DA9063_ADC_MODE 0x20
+
+/* DA9063_REG_ADC_CONT (addr=0x35) */
+#define DA9063_ADC_AUTO_VSYS_EN 0x01
+#define DA9063_ADC_AUTO_AD1_EN 0x02
+#define DA9063_ADC_AUTO_AD2_EN 0x04
+#define DA9063_ADC_AUTO_AD3_EN 0x08
+#define DA9063_ADC_AD1_ISRC_EN 0x10
+#define DA9063_ADC_AD2_ISRC_EN 0x20
+#define DA9063_ADC_AD3_ISRC_EN 0x40
+#define DA9063_COMP1V2_EN 0x80
+
+/* DA9063_REG_VSYS_MON (addr=0x36) */
+#define DA9063_VSYS_VAL_MASK 0xFF
+#define DA9063_VSYS_VAL_BASE 0x00
+
+/* DA9063_REG_ADC_RES_L (addr=0x37) */
+#define DA9063_ADC_RES_L_BITS 2
+#define DA9063_ADC_RES_L_MASK 0xC0
+
+/* DA9063_REG_ADC_RES_H (addr=0x38) */
+#define DA9063_ADC_RES_M_BITS 8
+#define DA9063_ADC_RES_M_MASK 0xFF
+
+/* DA9063_REG_(xxx_RES/ADC_RES_H) (addr=0x39-0x3F) */
+#define DA9063_ADC_VAL_MASK 0xFF
+
+/* DA9063_REG_COUNT_S (addr=0x40) */
+#define DA9063_RTC_READ 0x80
+#define DA9063_COUNT_SEC_MASK 0x3F
+
+/* DA9063_REG_COUNT_MI (addr=0x41) */
+#define DA9063_COUNT_MIN_MASK 0x3F
+
+/* DA9063_REG_COUNT_H (addr=0x42) */
+#define DA9063_COUNT_HOUR_MASK 0x1F
+
+/* DA9063_REG_COUNT_D (addr=0x43) */
+#define DA9063_COUNT_DAY_MASK 0x1F
+
+/* DA9063_REG_COUNT_MO (addr=0x44) */
+#define DA9063_COUNT_MONTH_MASK 0x0F
+
+/* DA9063_REG_COUNT_Y (addr=0x45) */
+#define DA9063_COUNT_YEAR_MASK 0x3F
+#define DA9063_MONITOR 0x40
+
+/* DA9063_REG_ALARM_MI (addr=0x46) */
+#define DA9063_ALARM_STATUS_ALARM 0x80
+#define DA9063_ALARM_STATUS_TICK 0x40
+#define DA9063_ALARM_MIN_MASK 0x3F
+
+/* DA9063_REG_ALARM_H (addr=0x47) */
+#define DA9063_ALARM_HOUR_MASK 0x1F
+
+/* DA9063_REG_ALARM_D (addr=0x48) */
+#define DA9063_ALARM_DAY_MASK 0x1F
+
+/* DA9063_REG_ALARM_MO (addr=0x49) */
+#define DA9063_TICK_WAKE 0x20
+#define DA9063_TICK_TYPE 0x10
+#define DA9063_TICK_TYPE_SEC 0x00
+#define DA9063_TICK_TYPE_MIN 0x10
+#define DA9063_ALARM_MONTH_MASK 0x0F
+
+/* DA9063_REG_ALARM_Y (addr=0x4A) */
+#define DA9063_TICK_ON 0x80
+#define DA9063_ALARM_ON 0x40
+#define DA9063_ALARM_YEAR_MASK 0x3F
+
+/* DA9063_REG_WAIT (addr=0x97)*/
+#define DA9063_REG_WAIT_TIME_MASK 0xF
+#define DA9063_WAIT_TIME_0_US 0x0
+#define DA9063_WAIT_TIME_512_US 0x1
+#define DA9063_WAIT_TIME_1_MS 0x2
+#define DA9063_WAIT_TIME_2_MS 0x3
+#define DA9063_WAIT_TIME_4_1_MS 0x4
+#define DA9063_WAIT_TIME_8_2_MS 0x5
+#define DA9063_WAIT_TIME_16_4_MS 0x6
+#define DA9063_WAIT_TIME_32_8_MS 0x7
+#define DA9063_WAIT_TIME_65_5_MS 0x8
+#define DA9063_WAIT_TIME_128_MS 0x9
+#define DA9063_WAIT_TIME_256_MS 0xA
+#define DA9063_WAIT_TIME_512_MS 0xB
+#define DA9063_WAIT_TIME_1_S 0xC
+#define DA9063_WAIT_TIME_2_1_S 0xD
+
+/* DA9063_REG_EN_32K (addr=0x98)*/
+#define DA9063_STABILIZ_TIME_MASK 0x7
+#define DA9063_CRYSTAL 0x08
+#define DA9063_DELAY_MODE 0x10
+#define DA9063_OUT_CLOCK 0x20
+#define DA9063_RTC_CLOCK 0x40
+#define DA9063_OUT_32K_EN 0x80
+
+/* DA9063_REG_CHIP_VARIANT */
+#define DA9063_CHIP_VARIANT_SHIFT 4
+
+/* DA9063_REG_BUCK_ILIM_A (addr=0x9A) */
+#define DA9063_BIO_ILIM_MASK 0x0F
+#define DA9063_BMEM_ILIM_MASK 0xF0
+
+/* DA9063_REG_BUCK_ILIM_B (addr=0x9B) */
+#define DA9063_BPRO_ILIM_MASK 0x0F
+#define DA9063_BPERI_ILIM_MASK 0xF0
+
+/* DA9063_REG_BUCK_ILIM_C (addr=0x9C) */
+#define DA9063_BCORE1_ILIM_MASK 0x0F
+#define DA9063_BCORE2_ILIM_MASK 0xF0
+
+/* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */
+#define DA9063_BUCK_FB_MASK 0x07
+#define DA9063_BUCK_PD_DIS_SHIFT 5
+#define DA9063_BUCK_MODE_MASK 0xC0
+#define DA9063_BUCK_MODE_MANUAL 0x00
+#define DA9063_BUCK_MODE_SLEEP 0x40
+#define DA9063_BUCK_MODE_SYNC 0x80
+#define DA9063_BUCK_MODE_AUTO 0xC0
+
+/* DA9063_REG_BPRO_CFG (addr=0x9F) */
+#define DA9063_BPRO_VTTR_EN 0x08
+#define DA9063_BPRO_VTT_EN 0x10
+
+/* DA9063_REG_VBxxxx_A/B (addr=0xA3-0xA8, 0xB4-0xB9) */
+#define DA9063_VBUCK_MASK 0x7F
+#define DA9063_VBUCK_BIAS 0
+#define DA9063_BUCK_SL 0x80
+
+/* DA9063_REG_VLDOx_A/B (addr=0xA9-0x3, 0xBA-0xC4) */
+#define DA9063_LDO_SL 0x80
+
+/* DA9063_REG_VLDO1_A/B (addr=0xA9, 0xBA) */
+#define DA9063_VLDO1_MASK 0x3F
+#define DA9063_VLDO1_BIAS 0
+
+/* DA9063_REG_VLDO2_A/B (addr=0xAA, 0xBB) */
+#define DA9063_VLDO2_MASK 0x3F
+#define DA9063_VLDO2_BIAS 0
+
+/* DA9063_REG_VLDO3_A/B (addr=0xAB, 0xBC) */
+#define DA9063_VLDO3_MASK 0x7F
+#define DA9063_VLDO3_BIAS 0
+
+/* DA9063_REG_VLDO4_A/B (addr=0xAC, 0xBD) */
+#define DA9063_VLDO4_MASK 0x7F
+#define DA9063_VLDO4_BIAS 0
+
+/* DA9063_REG_VLDO5_A/B (addr=0xAD, 0xBE) */
+#define DA9063_VLDO5_MASK 0x3F
+#define DA9063_VLDO5_BIAS 2
+
+/* DA9063_REG_VLDO6_A/B (addr=0xAE, 0xBF) */
+#define DA9063_VLDO6_MASK 0x3F
+#define DA9063_VLDO6_BIAS 2
+
+/* DA9063_REG_VLDO7_A/B (addr=0xAF, 0xC0) */
+#define DA9063_VLDO7_MASK 0x3F
+#define DA9063_VLDO7_BIAS 2
+
+/* DA9063_REG_VLDO8_A/B (addr=0xB0, 0xC1) */
+#define DA9063_VLDO8_MASK 0x3F
+#define DA9063_VLDO8_BIAS 2
+
+/* DA9063_REG_VLDO9_A/B (addr=0xB1, 0xC2) */
+#define DA9063_VLDO9_MASK 0x3F
+#define DA9063_VLDO9_BIAS 3
+
+/* DA9063_REG_VLDO10_A/B (addr=0xB2, 0xC3) */
+#define DA9063_VLDO10_MASK 0x3F
+#define DA9063_VLDO10_BIAS 2
+
+/* DA9063_REG_VLDO11_A/B (addr=0xB3, 0xC4) */
+#define DA9063_VLDO11_MASK 0x3F
+#define DA9063_VLDO11_BIAS 2
+
+/* DA9063_REG_GPO11_LED (addr=0xC6) */
+/* DA9063_REG_GPO14_LED (addr=0xC7) */
+/* DA9063_REG_GPO15_LED (addr=0xC8) */
+#define DA9063_GPIO_DIM 0x80
+#define DA9063_GPIO_PWM_MASK 0x7F
+
+/* DA9063_REG_CONFIG_H (addr=0x10D) */
+#define DA9063_PWM_CLK_MASK 0x01
+#define DA9063_PWM_CLK_PWM2MHZ 0x00
+#define DA9063_PWM_CLK_PWM1MHZ 0x01
+#define DA9063_LDO8_MODE_MASK 0x02
+#define DA9063_LDO8_MODE_LDO 0
+#define DA9063_LDO8_MODE_VIBR 0x02
+#define DA9063_MERGE_SENSE_MASK 0x04
+#define DA9063_MERGE_SENSE_GP_FB2 0x00
+#define DA9063_MERGE_SENSE_GPIO4 0x04
+#define DA9063_BCORE_MERGE 0x08
+#define DA9063_BPRO_OD 0x10
+#define DA9063_BCORE2_OD 0x20
+#define DA9063_BCORE1_OD 0x40
+#define DA9063_BUCK_MERGE 0x80
+
+/* DA9063_REG_CONFIG_I (addr=0x10E) */
+#define DA9063_NONKEY_PIN_MASK 0x03
+#define DA9063_NONKEY_PIN_PORT 0x00
+#define DA9063_NONKEY_PIN_SWDOWN 0x01
+#define DA9063_NONKEY_PIN_AUTODOWN 0x02
+#define DA9063_NONKEY_PIN_AUTOFLPRT 0x03
+
+/* DA9063_REG_MON_REG_5 (addr=0x116) */
+#define DA9063_MON_A8_IDX_MASK 0x07
+#define DA9063_MON_A8_IDX_NONE 0x00
+#define DA9063_MON_A8_IDX_BCORE1 0x01
+#define DA9063_MON_A8_IDX_BCORE2 0x02
+#define DA9063_MON_A8_IDX_BPRO 0x03
+#define DA9063_MON_A8_IDX_LDO3 0x04
+#define DA9063_MON_A8_IDX_LDO4 0x05
+#define DA9063_MON_A8_IDX_LDO11 0x06
+#define DA9063_MON_A9_IDX_MASK 0x70
+#define DA9063_MON_A9_IDX_NONE 0x00
+#define DA9063_MON_A9_IDX_BIO 0x01
+#define DA9063_MON_A9_IDX_BMEM 0x02
+#define DA9063_MON_A9_IDX_BPERI 0x03
+#define DA9063_MON_A9_IDX_LDO1 0x04
+#define DA9063_MON_A9_IDX_LDO2 0x05
+#define DA9063_MON_A9_IDX_LDO5 0x06
+
+/* DA9063_REG_MON_REG_6 (addr=0x117) */
+#define DA9063_MON_A10_IDX_MASK 0x07
+#define DA9063_MON_A10_IDX_NONE 0x00
+#define DA9063_MON_A10_IDX_LDO6 0x01
+#define DA9063_MON_A10_IDX_LDO7 0x02
+#define DA9063_MON_A10_IDX_LDO8 0x03
+#define DA9063_MON_A10_IDX_LDO9 0x04
+#define DA9063_MON_A10_IDX_LDO10 0x05
+
+#endif /* _DA9063_REG_H */
#include <mach/hardware.h>
+struct regmap;
+
/*
* Register values.
*/
/* Memory resources */
void __iomem *base;
+ struct regmap *regmap;
/* MFD cells */
struct mfd_cell cells[DAVINCI_VC_CELLS];
#ifndef MCP_H
#define MCP_H
+#include <linux/device.h>
+
struct mcp_ops;
struct mcp {
PALMAS_NUM_REGS,
};
+/* External controll signal name */
+enum {
+ PALMAS_EXT_CONTROL_ENABLE1 = 0x1,
+ PALMAS_EXT_CONTROL_ENABLE2 = 0x2,
+ PALMAS_EXT_CONTROL_NSLEEP = 0x4,
+};
+
+/*
+ * Palmas device resources can be controlled externally for
+ * enabling/disabling it rather than register write through i2c.
+ * Add the external controlled requestor ID for different resources.
+ */
+enum palmas_external_requestor_id {
+ PALMAS_EXTERNAL_REQSTR_ID_REGEN1,
+ PALMAS_EXTERNAL_REQSTR_ID_REGEN2,
+ PALMAS_EXTERNAL_REQSTR_ID_SYSEN1,
+ PALMAS_EXTERNAL_REQSTR_ID_SYSEN2,
+ PALMAS_EXTERNAL_REQSTR_ID_CLK32KG,
+ PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO,
+ PALMAS_EXTERNAL_REQSTR_ID_REGEN3,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS12,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS3,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS45,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS6,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS7,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS8,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS9,
+ PALMAS_EXTERNAL_REQSTR_ID_SMPS10,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO1,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO2,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO3,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO4,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO5,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO6,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO7,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO8,
+ PALMAS_EXTERNAL_REQSTR_ID_LDO9,
+ PALMAS_EXTERNAL_REQSTR_ID_LDOLN,
+ PALMAS_EXTERNAL_REQSTR_ID_LDOUSB,
+
+ /* Last entry */
+ PALMAS_EXTERNAL_REQSTR_ID_MAX,
+};
+
struct palmas_pmic_platform_data {
/* An array of pointers to regulator init data indexed by regulator
* ID
*/
int mux_from_pdata;
u8 pad1, pad2;
+ bool pm_off;
struct palmas_pmic_platform_data *pmic_pdata;
struct palmas_gpadc_platform_data *gpadc_pdata;
return regmap_irq_get_virq(palmas->irq_data, irq);
}
+
+int palmas_ext_control_req_config(struct palmas *palmas,
+ enum palmas_external_requestor_id ext_control_req_id,
+ int ext_ctrl, bool enable);
+
#endif /* __LINUX_MFD_PALMAS_H */
/* Driver for Realtek driver-based card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#ifndef __RTSX_COMMON_H
/* Driver for Realtek PCI-Express card reader
*
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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
*
* Author:
* Wei WANG <wei_wang@realsil.com.cn>
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
#ifndef __RTSX_PCI_H
#include <linux/sched.h>
#include <linux/pci.h>
-
-#include "rtsx_common.h"
+#include <linux/mfd/rtsx_common.h>
#define MAX_RW_REG_CNT 1024
#define CARD_SHARE_BAROSSA_SD 0x01
#define CARD_SHARE_BAROSSA_MS 0x02
+/* CARD_DRIVE_SEL */
+#define MS_DRIVE_8mA (0x01 << 6)
+#define MMC_DRIVE_8mA (0x01 << 4)
+#define XD_DRIVE_8mA (0x01 << 2)
+#define GPIO_DRIVE_8mA 0x01
+#define RTS5209_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\
+ XD_DRIVE_8mA | GPIO_DRIVE_8mA)
+#define RTL8411_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\
+ XD_DRIVE_8mA)
+#define RTSX_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | GPIO_DRIVE_8mA)
+
/* SD30_DRIVE_SEL */
#define DRIVER_TYPE_A 0x05
#define DRIVER_TYPE_B 0x03
#define DRIVER_TYPE_C 0x02
#define DRIVER_TYPE_D 0x01
+#define CFG_DRIVER_TYPE_A 0x02
+#define CFG_DRIVER_TYPE_B 0x03
+#define CFG_DRIVER_TYPE_C 0x01
+#define CFG_DRIVER_TYPE_D 0x00
/* FPDCTL */
#define SSC_POWER_DOWN 0x01
#define SAMPLE_VAR_CLK0 (0x01 << 4)
#define SAMPLE_VAR_CLK1 (0x02 << 4)
+/* HOST_SLEEP_STATE */
+#define HOST_ENTER_S1 1
+#define HOST_ENTER_S3 2
+
#define MS_CFG 0xFD40
#define MS_TPC 0xFD41
#define MS_TRANS_CFG 0xFD42
#define PME_FORCE_CTL 0xFE56
#define ASPM_FORCE_CTL 0xFE57
#define PM_CLK_FORCE_CTL 0xFE58
+#define FUNC_FORCE_CTL 0xFE59
#define PERST_GLITCH_WIDTH 0xFE5C
#define CHANGE_LINK_STATE 0xFE5B
#define RESET_LOAD_REG 0xFE5E
#define DUMMY_REG_RESET_0 0xFE90
+#define AUTOLOAD_CFG_BASE 0xFF00
+
+#define PM_CTRL1 0xFF44
+#define PM_CTRL2 0xFF45
+#define PM_CTRL3 0xFF46
+#define PM_CTRL4 0xFF47
+
/* Memory mapping */
#define SRAM_BASE 0xE600
#define RBUF_BASE 0xF400
#define PHY_FLD4 0x1E
#define PHY_DUM_REG 0x1F
+#define LCTLR 0x80
+#define PCR_SETTING_REG1 0x724
+#define PCR_SETTING_REG2 0x814
+#define PCR_SETTING_REG3 0x747
+
#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0)
struct rtsx_pcr;
u8 voltage);
unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr);
int (*conv_clk_and_div_n)(int clk, int dir);
+ void (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
+ void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
};
enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
struct completion *finish_me;
unsigned int cur_clock;
- bool ms_pmos;
bool remove_pci;
bool msi_en;
#define IC_VER_D 3
u8 ic_version;
+ u8 sd30_drive_sel_1v8;
+ u8 sd30_drive_sel_3v3;
+ u8 card_drive_sel;
+#define ASPM_L1_EN 0x02
+ u8 aspm_en;
+
+#define PCR_MS_PMOS (1 << 0)
+#define PCR_REVERSE_SOCKET (1 << 1)
+ u32 flags;
+
+ u32 tx_initial_phase;
+ u32 rx_initial_phase;
+
const u32 *sd_pull_ctl_enable_tbl;
const u32 *sd_pull_ctl_disable_tbl;
const u32 *ms_pull_ctl_enable_tbl;
#define PCI_VID(pcr) ((pcr)->pci->vendor)
#define PCI_PID(pcr) ((pcr)->pci->device)
+#define SDR104_PHASE(val) ((val) & 0xFF)
+#define SDR50_PHASE(val) (((val) >> 8) & 0xFF)
+#define DDR50_PHASE(val) (((val) >> 16) & 0xFF)
+#define SDR104_TX_PHASE(pcr) SDR104_PHASE((pcr)->tx_initial_phase)
+#define SDR50_TX_PHASE(pcr) SDR50_PHASE((pcr)->tx_initial_phase)
+#define DDR50_TX_PHASE(pcr) DDR50_PHASE((pcr)->tx_initial_phase)
+#define SDR104_RX_PHASE(pcr) SDR104_PHASE((pcr)->rx_initial_phase)
+#define SDR50_RX_PHASE(pcr) SDR50_PHASE((pcr)->rx_initial_phase)
+#define DDR50_RX_PHASE(pcr) DDR50_PHASE((pcr)->rx_initial_phase)
+#define SET_CLOCK_PHASE(sdr104, sdr50, ddr50) \
+ (((ddr50) << 16) | ((sdr50) << 8) | (sdr104))
+
void rtsx_pci_start_run(struct rtsx_pcr *pcr);
int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data);
int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data);
S2MPS11_BUCK8,
S2MPS11_BUCK9,
S2MPS11_BUCK10,
- S2MPS11_AP_EN32KHZ,
- S2MPS11_CP_EN32KHZ,
- S2MPS11_BT_EN32KHZ,
- S2MPS11_REG_MAX,
+ S2MPS11_REGULATOR_MAX,
};
#define S2MPS11_BUCK_MIN1 600000
#define S2MPS11_BUCK4_RAMP_EN_SHIFT 1
#define S2MPS11_BUCK6_RAMP_EN_SHIFT 0
#define S2MPS11_PMIC_EN_SHIFT 6
-#define S2MPS11_REGULATOR_MAX (S2MPS11_REG_MAX - 3)
#endif /* __LINUX_MFD_S2MPS11_H */
#define SEQ_STATUS BIT(5)
#define ADC_CLK 3000000
-#define MAX_CLK_DIV 7
#define TOTAL_STEPS 16
#define TOTAL_CHANNELS 8
#define TWL6040_GPO_MAX 3
+/* TODO: All platform data struct can be removed */
struct twl6040_codec_data {
u16 hs_left_step;
u16 hs_right_step;
int audpwron;
int power_count;
int rev;
- u8 vibra_ctrl_cache[2];
/* PLL configuration */
int pll;
#ifndef UCB1200_H
#define UCB1200_H
+#include <linux/device.h>
#include <linux/mfd/mcp.h>
#include <linux/gpio.h>
#include <linux/mutex.h>