Merge branch 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6
* 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6: (80 commits) mfd: Fix missing abx500 header file updates mfd: Add missing <linux/io.h> include to intel_msic x86, mrst: add platform support for MSIC MFD driver mfd: Expose TurnOnStatus in ab8500 sysfs mfd: Remove support for early drop ab8500 chip mfd: Add support for ab8500 v3.3 mfd: Add ab8500 interrupt disable hook mfd: Convert db8500-prcmu panic() into pr_crit() mfd: Refactor db8500-prcmu request_clock() function mfd: Rename db8500-prcmu init function mfd: Fix db5500-prcmu defines mfd: db8500-prcmu voltage domain consumers additions mfd: db8500-prcmu reset code retrieval mfd: db8500-prcmu tweak for modem wakeup mfd: Add db8500-pcmu watchdog accessor functions for watchdog mfd: hwacc power state db8500-prcmu accessor mfd: Add db8500-prcmu accessors for PLL and SGA clock mfd: Move to the new db500 PRCMU API mfd: Create a common interface for dbx500 PRCMU drivers mfd: Initialize DB8500 PRCMU regs ... Fix up trivial conflicts in arch/arm/mach-imx/mach-mx31moboard.c arch/arm/mach-omap2/board-omap3beagle.c arch/arm/mach-u300/include/mach/irqs.h drivers/mfd/wm831x-spi.c
This commit is contained in:
commit
a0a4194c94
|
@ -293,8 +293,7 @@ static struct mc13xxx_platform_data mc13783_pdata = {
|
||||||
.num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
|
.num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
|
||||||
|
|
||||||
},
|
},
|
||||||
.flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN |
|
.flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC,
|
||||||
MC13783_USE_RTC,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SPI */
|
/* SPI */
|
||||||
|
|
|
@ -492,7 +492,7 @@ static struct mc13xxx_platform_data mc13783_pdata = {
|
||||||
.regulators = mx31_3ds_regulators,
|
.regulators = mx31_3ds_regulators,
|
||||||
.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
|
.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
|
||||||
},
|
},
|
||||||
.flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
|
.flags = MC13XXX_USE_TOUCHSCREEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SPI */
|
/* SPI */
|
||||||
|
|
|
@ -112,8 +112,7 @@ static const struct spi_imx_master spi1_pdata __initconst = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
|
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
|
||||||
.flags = MC13XXX_USE_RTC |
|
.flags = MC13XXX_USE_RTC,
|
||||||
MC13XXX_USE_REGULATOR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct spi_board_info mc13783_spi_dev __initdata = {
|
static struct spi_board_info mc13783_spi_dev __initdata = {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
#include <linux/usb/otg.h>
|
#include <linux/usb/otg.h>
|
||||||
#include <linux/usb/ulpi.h>
|
#include <linux/usb/ulpi.h>
|
||||||
|
@ -225,7 +226,7 @@ static struct mc13xxx_regulator_init_data moboard_regulators[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mc13783_led_platform_data moboard_led[] = {
|
static struct mc13xxx_led_platform_data moboard_led[] = {
|
||||||
{
|
{
|
||||||
.id = MC13783_LED_R1,
|
.id = MC13783_LED_R1,
|
||||||
.name = "coreboard-led-4:red",
|
.name = "coreboard-led-4:red",
|
||||||
|
@ -258,7 +259,7 @@ static struct mc13783_led_platform_data moboard_led[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mc13783_leds_platform_data moboard_leds = {
|
static struct mc13xxx_leds_platform_data moboard_leds = {
|
||||||
.num_leds = ARRAY_SIZE(moboard_led),
|
.num_leds = ARRAY_SIZE(moboard_led),
|
||||||
.led = moboard_led,
|
.led = moboard_led,
|
||||||
.flags = MC13783_LED_SLEWLIMTC,
|
.flags = MC13783_LED_SLEWLIMTC,
|
||||||
|
@ -267,14 +268,20 @@ static struct mc13783_leds_platform_data moboard_leds = {
|
||||||
.tc2_period = MC13783_LED_PERIOD_10MS,
|
.tc2_period = MC13783_LED_PERIOD_10MS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct mc13xxx_buttons_platform_data moboard_buttons = {
|
||||||
|
.b1on_flags = MC13783_BUTTON_DBNC_750MS | MC13783_BUTTON_ENABLE |
|
||||||
|
MC13783_BUTTON_POL_INVERT,
|
||||||
|
.b1on_key = KEY_POWER,
|
||||||
|
};
|
||||||
|
|
||||||
static struct mc13xxx_platform_data moboard_pmic = {
|
static struct mc13xxx_platform_data moboard_pmic = {
|
||||||
.regulators = {
|
.regulators = {
|
||||||
.regulators = moboard_regulators,
|
.regulators = moboard_regulators,
|
||||||
.num_regulators = ARRAY_SIZE(moboard_regulators),
|
.num_regulators = ARRAY_SIZE(moboard_regulators),
|
||||||
},
|
},
|
||||||
.leds = &moboard_leds,
|
.leds = &moboard_leds,
|
||||||
.flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
|
.buttons = &moboard_buttons,
|
||||||
MC13XXX_USE_ADC | MC13XXX_USE_LED,
|
.flags = MC13XXX_USE_RTC | MC13XXX_USE_ADC,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct spi_board_info moboard_spi_board_info[] __initdata = {
|
static struct spi_board_info moboard_spi_board_info[] __initdata = {
|
||||||
|
|
|
@ -268,8 +268,7 @@ static struct mc13xxx_platform_data pcm038_pmic = {
|
||||||
.regulators = pcm038_regulators,
|
.regulators = pcm038_regulators,
|
||||||
.num_regulators = ARRAY_SIZE(pcm038_regulators),
|
.num_regulators = ARRAY_SIZE(pcm038_regulators),
|
||||||
},
|
},
|
||||||
.flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
|
.flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN,
|
||||||
MC13783_USE_TOUCHSCREEN,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct spi_board_info pcm038_spi_board_info[] __initdata = {
|
static struct spi_board_info pcm038_spi_board_info[] __initdata = {
|
||||||
|
|
|
@ -565,7 +565,7 @@ static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mc13xxx_platform_data mx51_efika_mc13892_data = {
|
static struct mc13xxx_platform_data mx51_efika_mc13892_data = {
|
||||||
.flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR,
|
.flags = MC13XXX_USE_RTC,
|
||||||
.regulators = {
|
.regulators = {
|
||||||
.num_regulators = ARRAY_SIZE(mx51_efika_regulators),
|
.num_regulators = ARRAY_SIZE(mx51_efika_regulators),
|
||||||
.regulators = mx51_efika_regulators,
|
.regulators = mx51_efika_regulators,
|
||||||
|
|
|
@ -14,7 +14,6 @@ config ARCH_OMAP2PLUS_TYPICAL
|
||||||
select SERIAL_OMAP_CONSOLE
|
select SERIAL_OMAP_CONSOLE
|
||||||
select I2C
|
select I2C
|
||||||
select I2C_OMAP
|
select I2C_OMAP
|
||||||
select MFD_SUPPORT
|
|
||||||
select MENELAUS if ARCH_OMAP2
|
select MENELAUS if ARCH_OMAP2
|
||||||
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
|
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
|
||||||
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
|
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
|
||||||
|
|
|
@ -378,7 +378,8 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
|
||||||
static int __init omap3_beagle_i2c_init(void)
|
static int __init omap3_beagle_i2c_init(void)
|
||||||
{
|
{
|
||||||
omap3_pmic_get_config(&beagle_twldata,
|
omap3_pmic_get_config(&beagle_twldata,
|
||||||
TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
|
TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
|
||||||
|
TWL_COMMON_PDATA_AUDIO,
|
||||||
TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
|
TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
|
||||||
|
|
||||||
beagle_twldata.vpll2->constraints.name = "VDVI";
|
beagle_twldata.vpll2->constraints.name = "VDVI";
|
||||||
|
@ -444,9 +445,15 @@ static struct platform_device keys_gpio = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct platform_device madc_hwmon = {
|
||||||
|
.name = "twl4030_madc_hwmon",
|
||||||
|
.id = -1,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *omap3_beagle_devices[] __initdata = {
|
static struct platform_device *omap3_beagle_devices[] __initdata = {
|
||||||
&leds_gpio,
|
&leds_gpio,
|
||||||
&keys_gpio,
|
&keys_gpio,
|
||||||
|
&madc_hwmon,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
|
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
|
||||||
|
|
|
@ -256,57 +256,8 @@ static struct ab3100_platform_data ab3100_plf_data = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_AB3550_CORE
|
|
||||||
static struct abx500_init_settings ab3550_init_settings[] = {
|
|
||||||
{
|
|
||||||
.bank = 0,
|
|
||||||
.reg = AB3550_IMR1,
|
|
||||||
.setting = 0xff
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.bank = 0,
|
|
||||||
.reg = AB3550_IMR2,
|
|
||||||
.setting = 0xff
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.bank = 0,
|
|
||||||
.reg = AB3550_IMR3,
|
|
||||||
.setting = 0xff
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.bank = 0,
|
|
||||||
.reg = AB3550_IMR4,
|
|
||||||
.setting = 0xff
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.bank = 0,
|
|
||||||
.reg = AB3550_IMR5,
|
|
||||||
/* The two most significant bits are not used */
|
|
||||||
.setting = 0x3f
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ab3550_platform_data ab3550_plf_data = {
|
|
||||||
.irq = {
|
|
||||||
.base = IRQ_AB3550_BASE,
|
|
||||||
.count = (IRQ_AB3550_END - IRQ_AB3550_BASE + 1),
|
|
||||||
},
|
|
||||||
.dev_data = {
|
|
||||||
},
|
|
||||||
.init_settings = ab3550_init_settings,
|
|
||||||
.init_settings_sz = ARRAY_SIZE(ab3550_init_settings),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
|
static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
|
||||||
#if defined(CONFIG_AB3550_CORE)
|
#ifdef CONFIG_AB3100_CORE
|
||||||
{
|
|
||||||
.type = "ab3550",
|
|
||||||
.addr = 0x4A,
|
|
||||||
.irq = IRQ_U300_IRQ0_EXT,
|
|
||||||
.platform_data = &ab3550_plf_data,
|
|
||||||
},
|
|
||||||
#elif defined(CONFIG_AB3100_CORE)
|
|
||||||
{
|
{
|
||||||
.type = "ab3100",
|
.type = "ab3100",
|
||||||
.addr = 0x48,
|
.addr = 0x48,
|
||||||
|
|
|
@ -117,14 +117,6 @@
|
||||||
#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END)
|
#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Optional AB3550 mixsig chip */
|
#define NR_IRQS (IRQ_U300_GPIO_END)
|
||||||
#ifdef CONFIG_AB3550_CORE
|
|
||||||
#define IRQ_AB3550_BASE (IRQ_U300_GPIO_END)
|
|
||||||
#define IRQ_AB3550_END (IRQ_AB3550_BASE + 38)
|
|
||||||
#else
|
|
||||||
#define IRQ_AB3550_END (IRQ_U300_GPIO_END)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NR_IRQS (IRQ_AB3550_END)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/amba/bus.h>
|
#include <linux/amba/bus.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/mfd/ab5500/ab5500.h>
|
||||||
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
@ -87,7 +88,6 @@ static struct lm3530_platform_data u5500_als_platform_data = {
|
||||||
.brt_val = 0x7F, /* Max brightness */
|
.brt_val = 0x7F, /* Max brightness */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct i2c_board_info __initdata u5500_i2c2_devices[] = {
|
static struct i2c_board_info __initdata u5500_i2c2_devices[] = {
|
||||||
{
|
{
|
||||||
/* Backlight */
|
/* Backlight */
|
||||||
|
@ -101,6 +101,30 @@ static void __init u5500_i2c_init(void)
|
||||||
db5500_add_i2c2(&u5500_i2c2_data);
|
db5500_add_i2c2(&u5500_i2c2_data);
|
||||||
i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices));
|
i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ab5500_platform_data ab5500_plf_data = {
|
||||||
|
.irq = {
|
||||||
|
.base = 0,
|
||||||
|
.count = 0,
|
||||||
|
},
|
||||||
|
.init_settings = NULL,
|
||||||
|
.init_settings_sz = 0,
|
||||||
|
.pm_power_off = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device ab5500_device = {
|
||||||
|
.name = "ab5500-core",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &ab5500_plf_data,
|
||||||
|
},
|
||||||
|
.num_resources = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device *u5500_platform_devices[] __initdata = {
|
||||||
|
&ab5500_device,
|
||||||
|
};
|
||||||
|
|
||||||
static void __init u5500_uart_init(void)
|
static void __init u5500_uart_init(void)
|
||||||
{
|
{
|
||||||
db5500_add_uart0(NULL);
|
db5500_add_uart0(NULL);
|
||||||
|
@ -115,6 +139,9 @@ static void __init u5500_init_machine(void)
|
||||||
u5500_i2c_init();
|
u5500_i2c_init();
|
||||||
u5500_sdi_init();
|
u5500_sdi_init();
|
||||||
u5500_uart_init();
|
u5500_uart_init();
|
||||||
|
|
||||||
|
platform_add_devices(u5500_platform_devices,
|
||||||
|
ARRAY_SIZE(u5500_platform_devices));
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(U5500, "ST-Ericsson U5500 Platform")
|
MACHINE_START(U5500, "ST-Ericsson U5500 Platform")
|
||||||
|
|
|
@ -47,6 +47,6 @@ void __init ux500_init_irq(void)
|
||||||
if (cpu_is_u5500())
|
if (cpu_is_u5500())
|
||||||
db5500_prcmu_early_init();
|
db5500_prcmu_early_init();
|
||||||
if (cpu_is_u8500())
|
if (cpu_is_u8500())
|
||||||
prcmu_early_init();
|
db8500_prcmu_early_init();
|
||||||
clk_init();
|
clk_init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _ASM_X86_INTEL_SCU_IPC_H_
|
#ifndef _ASM_X86_INTEL_SCU_IPC_H_
|
||||||
#define _ASM_X86_INTEL_SCU_IPC_H_
|
#define _ASM_X86_INTEL_SCU_IPC_H_
|
||||||
|
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
#define IPCMSG_VRTC 0xFA /* Set vRTC device */
|
#define IPCMSG_VRTC 0xFA /* Set vRTC device */
|
||||||
|
|
||||||
/* Command id associated with message IPCMSG_VRTC */
|
/* Command id associated with message IPCMSG_VRTC */
|
||||||
|
@ -44,4 +46,24 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data);
|
||||||
/* Update FW version */
|
/* Update FW version */
|
||||||
int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
|
int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
|
||||||
|
|
||||||
|
extern struct blocking_notifier_head intel_scu_notifier;
|
||||||
|
|
||||||
|
static inline void intel_scu_notifier_add(struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
blocking_notifier_chain_register(&intel_scu_notifier, nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void intel_scu_notifier_remove(struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int intel_scu_notifier_post(unsigned long v, void *p)
|
||||||
|
{
|
||||||
|
return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCU_AVAILABLE 1
|
||||||
|
#define SCU_DOWN 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
#include <linux/mfd/intel_msic.h>
|
||||||
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/mpspec_def.h>
|
#include <asm/mpspec_def.h>
|
||||||
|
@ -483,6 +485,128 @@ static void __init *no_platform_data(void *info)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct resource msic_resources[] = {
|
||||||
|
{
|
||||||
|
.start = INTEL_MSIC_IRQ_PHYS_BASE,
|
||||||
|
.end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct intel_msic_platform_data msic_pdata;
|
||||||
|
|
||||||
|
static struct platform_device msic_device = {
|
||||||
|
.name = "intel_msic",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &msic_pdata,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(msic_resources),
|
||||||
|
.resource = msic_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool mrst_has_msic(void)
|
||||||
|
{
|
||||||
|
return mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msic_scu_status_change(struct notifier_block *nb,
|
||||||
|
unsigned long code, void *data)
|
||||||
|
{
|
||||||
|
if (code == SCU_DOWN) {
|
||||||
|
platform_device_unregister(&msic_device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform_device_register(&msic_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init msic_init(void)
|
||||||
|
{
|
||||||
|
static struct notifier_block msic_scu_notifier = {
|
||||||
|
.notifier_call = msic_scu_status_change,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to be sure that the SCU IPC is ready before MSIC device
|
||||||
|
* can be registered.
|
||||||
|
*/
|
||||||
|
if (mrst_has_msic())
|
||||||
|
intel_scu_notifier_add(&msic_scu_notifier);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
arch_initcall(msic_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msic_generic_platform_data - sets generic platform data for the block
|
||||||
|
* @info: pointer to the SFI device table entry for this block
|
||||||
|
* @block: MSIC block
|
||||||
|
*
|
||||||
|
* Function sets IRQ number from the SFI table entry for given device to
|
||||||
|
* the MSIC platform data.
|
||||||
|
*/
|
||||||
|
static void *msic_generic_platform_data(void *info, enum intel_msic_block block)
|
||||||
|
{
|
||||||
|
struct sfi_device_table_entry *entry = info;
|
||||||
|
|
||||||
|
BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST);
|
||||||
|
msic_pdata.irq[block] = entry->irq;
|
||||||
|
|
||||||
|
return no_platform_data(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *msic_battery_platform_data(void *info)
|
||||||
|
{
|
||||||
|
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *msic_gpio_platform_data(void *info)
|
||||||
|
{
|
||||||
|
static struct intel_msic_gpio_pdata pdata;
|
||||||
|
int gpio = get_gpio_by_name("msic_gpio_base");
|
||||||
|
|
||||||
|
if (gpio < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pdata.gpio_base = gpio;
|
||||||
|
msic_pdata.gpio = &pdata;
|
||||||
|
|
||||||
|
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *msic_audio_platform_data(void *info)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
pdev = platform_device_register_simple("sst-platform", -1, NULL, 0);
|
||||||
|
if (IS_ERR(pdev)) {
|
||||||
|
pr_err("failed to create audio platform device\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *msic_power_btn_platform_data(void *info)
|
||||||
|
{
|
||||||
|
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *msic_ocd_platform_data(void *info)
|
||||||
|
{
|
||||||
|
static struct intel_msic_ocd_pdata pdata;
|
||||||
|
int gpio = get_gpio_by_name("ocd_gpio");
|
||||||
|
|
||||||
|
if (gpio < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pdata.gpio = gpio;
|
||||||
|
msic_pdata.ocd = &pdata;
|
||||||
|
|
||||||
|
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct devs_id __initconst device_ids[] = {
|
static const struct devs_id __initconst device_ids[] = {
|
||||||
{"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data},
|
{"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data},
|
||||||
{"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data},
|
{"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data},
|
||||||
|
@ -491,7 +615,14 @@ static const struct devs_id __initconst device_ids[] = {
|
||||||
{"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data},
|
{"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data},
|
||||||
{"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data},
|
{"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data},
|
||||||
{"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data},
|
{"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data},
|
||||||
{"msic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data},
|
|
||||||
|
/* MSIC subdevices */
|
||||||
|
{"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data},
|
||||||
|
{"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data},
|
||||||
|
{"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data},
|
||||||
|
{"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data},
|
||||||
|
{"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data},
|
||||||
|
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -558,6 +689,9 @@ static void __init intel_scu_i2c_device_register(int bus,
|
||||||
i2c_devs[i2c_next_dev++] = new_dev;
|
i2c_devs[i2c_next_dev++] = new_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLOCKING_NOTIFIER_HEAD(intel_scu_notifier);
|
||||||
|
EXPORT_SYMBOL_GPL(intel_scu_notifier);
|
||||||
|
|
||||||
/* Called by IPC driver */
|
/* Called by IPC driver */
|
||||||
void intel_scu_devices_create(void)
|
void intel_scu_devices_create(void)
|
||||||
{
|
{
|
||||||
|
@ -582,6 +716,7 @@ void intel_scu_devices_create(void)
|
||||||
} else
|
} else
|
||||||
i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
|
i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
|
||||||
}
|
}
|
||||||
|
intel_scu_notifier_post(SCU_AVAILABLE, 0L);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(intel_scu_devices_create);
|
EXPORT_SYMBOL_GPL(intel_scu_devices_create);
|
||||||
|
|
||||||
|
@ -590,6 +725,8 @@ void intel_scu_devices_destroy(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
intel_scu_notifier_post(SCU_DOWN, 0L);
|
||||||
|
|
||||||
for (i = 0; i < ipc_next_dev; i++)
|
for (i = 0; i < ipc_next_dev; i++)
|
||||||
platform_device_del(ipc_devs[i]);
|
platform_device_del(ipc_devs[i]);
|
||||||
}
|
}
|
||||||
|
@ -606,19 +743,37 @@ static void __init install_irq_resource(struct platform_device *pdev, int irq)
|
||||||
platform_device_add_resources(pdev, &res, 1);
|
platform_device_add_resources(pdev, &res, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init sfi_handle_ipc_dev(struct platform_device *pdev)
|
static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *entry)
|
||||||
{
|
{
|
||||||
const struct devs_id *dev = device_ids;
|
const struct devs_id *dev = device_ids;
|
||||||
|
struct platform_device *pdev;
|
||||||
void *pdata = NULL;
|
void *pdata = NULL;
|
||||||
|
|
||||||
while (dev->name[0]) {
|
while (dev->name[0]) {
|
||||||
if (dev->type == SFI_DEV_TYPE_IPC &&
|
if (dev->type == SFI_DEV_TYPE_IPC &&
|
||||||
!strncmp(dev->name, pdev->name, SFI_NAME_LEN)) {
|
!strncmp(dev->name, entry->name, SFI_NAME_LEN)) {
|
||||||
pdata = dev->get_platform_data(pdev);
|
pdata = dev->get_platform_data(entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev++;
|
dev++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On Medfield the platform device creation is handled by the MSIC
|
||||||
|
* MFD driver so we don't need to do it here.
|
||||||
|
*/
|
||||||
|
if (mrst_has_msic())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* ID as IRQ is a hack that will go away */
|
||||||
|
pdev = platform_device_alloc(entry->name, entry->irq);
|
||||||
|
if (pdev == NULL) {
|
||||||
|
pr_err("out of memory for SFI platform device '%s'.\n",
|
||||||
|
entry->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
install_irq_resource(pdev, entry->irq);
|
||||||
|
|
||||||
pdev->dev.platform_data = pdata;
|
pdev->dev.platform_data = pdata;
|
||||||
intel_scu_device_register(pdev);
|
intel_scu_device_register(pdev);
|
||||||
}
|
}
|
||||||
|
@ -671,7 +826,6 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
|
||||||
struct sfi_device_table_entry *pentry;
|
struct sfi_device_table_entry *pentry;
|
||||||
struct spi_board_info spi_info;
|
struct spi_board_info spi_info;
|
||||||
struct i2c_board_info i2c_info;
|
struct i2c_board_info i2c_info;
|
||||||
struct platform_device *pdev;
|
|
||||||
int num, i, bus;
|
int num, i, bus;
|
||||||
int ioapic;
|
int ioapic;
|
||||||
struct io_apic_irq_attr irq_attr;
|
struct io_apic_irq_attr irq_attr;
|
||||||
|
@ -699,17 +853,9 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
|
||||||
|
|
||||||
switch (pentry->type) {
|
switch (pentry->type) {
|
||||||
case SFI_DEV_TYPE_IPC:
|
case SFI_DEV_TYPE_IPC:
|
||||||
/* ID as IRQ is a hack that will go away */
|
|
||||||
pdev = platform_device_alloc(pentry->name, irq);
|
|
||||||
if (pdev == NULL) {
|
|
||||||
pr_err("out of memory for SFI platform device '%s'.\n",
|
|
||||||
pentry->name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
install_irq_resource(pdev, irq);
|
|
||||||
pr_debug("info[%2d]: IPC bus, name = %16.16s, "
|
pr_debug("info[%2d]: IPC bus, name = %16.16s, "
|
||||||
"irq = 0x%2x\n", i, pentry->name, irq);
|
"irq = 0x%2x\n", i, pentry->name, pentry->irq);
|
||||||
sfi_handle_ipc_dev(pdev);
|
sfi_handle_ipc_dev(pentry);
|
||||||
break;
|
break;
|
||||||
case SFI_DEV_TYPE_SPI:
|
case SFI_DEV_TYPE_SPI:
|
||||||
memset(&spi_info, 0, sizeof(spi_info));
|
memset(&spi_info, 0, sizeof(spi_info));
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/mfd/db8500-prcmu.h>
|
#include <linux/mfd/dbx500-prcmu.h>
|
||||||
#include <mach/id.h>
|
#include <mach/id.h>
|
||||||
|
|
||||||
static struct cpufreq_frequency_table freq_table[] = {
|
static struct cpufreq_frequency_table freq_table[] = {
|
||||||
|
|
|
@ -189,7 +189,7 @@ config GPIO_U300
|
||||||
|
|
||||||
config GPIO_VX855
|
config GPIO_VX855
|
||||||
tristate "VIA VX855/VX875 GPIO"
|
tristate "VIA VX855/VX875 GPIO"
|
||||||
depends on MFD_SUPPORT && PCI
|
depends on PCI
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
select MFD_VX855
|
select MFD_VX855
|
||||||
help
|
help
|
||||||
|
@ -428,7 +428,6 @@ config GPIO_TIMBERDALE
|
||||||
config GPIO_RDC321X
|
config GPIO_RDC321X
|
||||||
tristate "RDC R-321x GPIO support"
|
tristate "RDC R-321x GPIO support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
select MFD_SUPPORT
|
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
select MFD_RDC321X
|
select MFD_RDC321X
|
||||||
help
|
help
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#define MC13783_ADC_NAME "mc13783-adc"
|
#define MC13783_ADC_NAME "mc13783-adc"
|
||||||
|
|
||||||
struct mc13783_adc_priv {
|
struct mc13783_adc_priv {
|
||||||
struct mc13783 *mc13783;
|
struct mc13xxx *mc13xxx;
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ static int mc13783_adc_read(struct device *dev,
|
||||||
unsigned int sample[4];
|
unsigned int sample[4];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = mc13783_adc_do_conversion(priv->mc13783,
|
ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
|
||||||
MC13783_ADC_MODE_MULT_CHAN,
|
MC13XXX_ADC_MODE_MULT_CHAN,
|
||||||
channel, sample);
|
channel, sample);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -147,9 +147,9 @@ static const struct attribute_group mc13783_group_ts = {
|
||||||
static int mc13783_adc_use_touchscreen(struct platform_device *pdev)
|
static int mc13783_adc_use_touchscreen(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
|
struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
|
||||||
unsigned flags = mc13783_get_flags(priv->mc13783);
|
unsigned flags = mc13xxx_get_flags(priv->mc13xxx);
|
||||||
|
|
||||||
return flags & MC13783_USE_TOUCHSCREEN;
|
return flags & MC13XXX_USE_TOUCHSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init mc13783_adc_probe(struct platform_device *pdev)
|
static int __init mc13783_adc_probe(struct platform_device *pdev)
|
||||||
|
@ -161,7 +161,7 @@ static int __init mc13783_adc_probe(struct platform_device *pdev)
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
|
priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, priv);
|
platform_set_drvdata(pdev, priv);
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,6 @@ config I2C_I801
|
||||||
config I2C_ISCH
|
config I2C_ISCH
|
||||||
tristate "Intel SCH SMBus 1.0"
|
tristate "Intel SCH SMBus 1.0"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
select MFD_CORE
|
|
||||||
select LPC_SCH
|
select LPC_SCH
|
||||||
help
|
help
|
||||||
Say Y here if you want to use SMBus controller on the Intel SCH
|
Say Y here if you want to use SMBus controller on the Intel SCH
|
||||||
|
|
|
@ -134,6 +134,16 @@ config INPUT_MAX8925_ONKEY
|
||||||
To compile this driver as a module, choose M here: the module
|
To compile this driver as a module, choose M here: the module
|
||||||
will be called max8925_onkey.
|
will be called max8925_onkey.
|
||||||
|
|
||||||
|
config INPUT_MC13783_PWRBUTTON
|
||||||
|
tristate "MC13783 ON buttons"
|
||||||
|
depends on MFD_MC13783
|
||||||
|
help
|
||||||
|
Support the ON buttons of MC13783 PMIC as an input device
|
||||||
|
reporting power button status.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the module
|
||||||
|
will be called mc13783-pwrbutton.
|
||||||
|
|
||||||
config INPUT_MMA8450
|
config INPUT_MMA8450
|
||||||
tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer"
|
tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
|
||||||
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
|
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
|
||||||
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
|
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
|
||||||
obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
|
obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
|
||||||
|
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
|
||||||
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
|
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
|
||||||
obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o
|
obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o
|
||||||
obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
|
obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2011 Philippe Rétornaz
|
||||||
|
*
|
||||||
|
* Based on twl4030-pwrbutton driver by:
|
||||||
|
* Peter De Schrijver <peter.de-schrijver@nokia.com>
|
||||||
|
* Felipe Balbi <felipe.balbi@nokia.com>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General
|
||||||
|
* Public License. See the file "COPYING" in the main directory of this
|
||||||
|
* archive for more details.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mfd/mc13783.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
struct mc13783_pwrb {
|
||||||
|
struct input_dev *pwr;
|
||||||
|
struct mc13xxx *mc13783;
|
||||||
|
#define MC13783_PWRB_B1_POL_INVERT (1 << 0)
|
||||||
|
#define MC13783_PWRB_B2_POL_INVERT (1 << 1)
|
||||||
|
#define MC13783_PWRB_B3_POL_INVERT (1 << 2)
|
||||||
|
int flags;
|
||||||
|
unsigned short keymap[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MC13783_REG_INTERRUPT_SENSE_1 5
|
||||||
|
#define MC13783_IRQSENSE1_ONOFD1S (1 << 3)
|
||||||
|
#define MC13783_IRQSENSE1_ONOFD2S (1 << 4)
|
||||||
|
#define MC13783_IRQSENSE1_ONOFD3S (1 << 5)
|
||||||
|
|
||||||
|
#define MC13783_REG_POWER_CONTROL_2 15
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON1BDBNC 4
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON2BDBNC 6
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON3BDBNC 8
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON1BRSTEN (1 << 1)
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON2BRSTEN (1 << 2)
|
||||||
|
#define MC13783_POWER_CONTROL_2_ON3BRSTEN (1 << 3)
|
||||||
|
|
||||||
|
static irqreturn_t button_irq(int irq, void *_priv)
|
||||||
|
{
|
||||||
|
struct mc13783_pwrb *priv = _priv;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
mc13xxx_irq_ack(priv->mc13783, irq);
|
||||||
|
mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val);
|
||||||
|
|
||||||
|
switch (irq) {
|
||||||
|
case MC13783_IRQ_ONOFD1:
|
||||||
|
val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0;
|
||||||
|
if (priv->flags & MC13783_PWRB_B1_POL_INVERT)
|
||||||
|
val ^= 1;
|
||||||
|
input_report_key(priv->pwr, priv->keymap[0], val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MC13783_IRQ_ONOFD2:
|
||||||
|
val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0;
|
||||||
|
if (priv->flags & MC13783_PWRB_B2_POL_INVERT)
|
||||||
|
val ^= 1;
|
||||||
|
input_report_key(priv->pwr, priv->keymap[1], val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MC13783_IRQ_ONOFD3:
|
||||||
|
val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0;
|
||||||
|
if (priv->flags & MC13783_PWRB_B3_POL_INVERT)
|
||||||
|
val ^= 1;
|
||||||
|
input_report_key(priv->pwr, priv->keymap[2], val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_sync(priv->pwr);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit mc13783_pwrbutton_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
const struct mc13xxx_buttons_platform_data *pdata;
|
||||||
|
struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
struct input_dev *pwr;
|
||||||
|
struct mc13783_pwrb *priv;
|
||||||
|
int err = 0;
|
||||||
|
int reg = 0;
|
||||||
|
|
||||||
|
pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(&pdev->dev, "missing platform data\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwr = input_allocate_device();
|
||||||
|
if (!pwr) {
|
||||||
|
dev_dbg(&pdev->dev, "Can't allocate power button\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
dev_dbg(&pdev->dev, "Can't allocate power button\n");
|
||||||
|
goto free_input_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg |= (pdata->b1on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
|
||||||
|
reg |= (pdata->b2on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
|
||||||
|
reg |= (pdata->b3on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
|
||||||
|
|
||||||
|
priv->pwr = pwr;
|
||||||
|
priv->mc13783 = mc13783;
|
||||||
|
|
||||||
|
mc13xxx_lock(mc13783);
|
||||||
|
|
||||||
|
if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) {
|
||||||
|
priv->keymap[0] = pdata->b1on_key;
|
||||||
|
if (pdata->b1on_key != KEY_RESERVED)
|
||||||
|
__set_bit(pdata->b1on_key, pwr->keybit);
|
||||||
|
|
||||||
|
if (pdata->b1on_flags & MC13783_BUTTON_POL_INVERT)
|
||||||
|
priv->flags |= MC13783_PWRB_B1_POL_INVERT;
|
||||||
|
|
||||||
|
if (pdata->b1on_flags & MC13783_BUTTON_RESET_EN)
|
||||||
|
reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN;
|
||||||
|
|
||||||
|
err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD1,
|
||||||
|
button_irq, "b1on", priv);
|
||||||
|
if (err) {
|
||||||
|
dev_dbg(&pdev->dev, "Can't request irq\n");
|
||||||
|
goto free_priv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) {
|
||||||
|
priv->keymap[1] = pdata->b2on_key;
|
||||||
|
if (pdata->b2on_key != KEY_RESERVED)
|
||||||
|
__set_bit(pdata->b2on_key, pwr->keybit);
|
||||||
|
|
||||||
|
if (pdata->b2on_flags & MC13783_BUTTON_POL_INVERT)
|
||||||
|
priv->flags |= MC13783_PWRB_B2_POL_INVERT;
|
||||||
|
|
||||||
|
if (pdata->b2on_flags & MC13783_BUTTON_RESET_EN)
|
||||||
|
reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN;
|
||||||
|
|
||||||
|
err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD2,
|
||||||
|
button_irq, "b2on", priv);
|
||||||
|
if (err) {
|
||||||
|
dev_dbg(&pdev->dev, "Can't request irq\n");
|
||||||
|
goto free_irq_b1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) {
|
||||||
|
priv->keymap[2] = pdata->b3on_key;
|
||||||
|
if (pdata->b3on_key != KEY_RESERVED)
|
||||||
|
__set_bit(pdata->b3on_key, pwr->keybit);
|
||||||
|
|
||||||
|
if (pdata->b3on_flags & MC13783_BUTTON_POL_INVERT)
|
||||||
|
priv->flags |= MC13783_PWRB_B3_POL_INVERT;
|
||||||
|
|
||||||
|
if (pdata->b3on_flags & MC13783_BUTTON_RESET_EN)
|
||||||
|
reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN;
|
||||||
|
|
||||||
|
err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD3,
|
||||||
|
button_irq, "b3on", priv);
|
||||||
|
if (err) {
|
||||||
|
dev_dbg(&pdev->dev, "Can't request irq: %d\n", err);
|
||||||
|
goto free_irq_b2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mc13xxx_reg_rmw(mc13783, MC13783_REG_POWER_CONTROL_2, 0x3FE, reg);
|
||||||
|
|
||||||
|
mc13xxx_unlock(mc13783);
|
||||||
|
|
||||||
|
pwr->name = "mc13783_pwrbutton";
|
||||||
|
pwr->phys = "mc13783_pwrbutton/input0";
|
||||||
|
pwr->dev.parent = &pdev->dev;
|
||||||
|
|
||||||
|
pwr->keycode = priv->keymap;
|
||||||
|
pwr->keycodemax = ARRAY_SIZE(priv->keymap);
|
||||||
|
pwr->keycodesize = sizeof(priv->keymap[0]);
|
||||||
|
__set_bit(EV_KEY, pwr->evbit);
|
||||||
|
|
||||||
|
err = input_register_device(pwr);
|
||||||
|
if (err) {
|
||||||
|
dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
|
||||||
|
goto free_irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, priv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
free_irq:
|
||||||
|
mc13xxx_lock(mc13783);
|
||||||
|
|
||||||
|
if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD3, priv);
|
||||||
|
|
||||||
|
free_irq_b2:
|
||||||
|
if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD2, priv);
|
||||||
|
|
||||||
|
free_irq_b1:
|
||||||
|
if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD1, priv);
|
||||||
|
|
||||||
|
free_priv:
|
||||||
|
mc13xxx_unlock(mc13783);
|
||||||
|
kfree(priv);
|
||||||
|
|
||||||
|
free_input_dev:
|
||||||
|
input_free_device(pwr);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit mc13783_pwrbutton_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mc13783_pwrb *priv = platform_get_drvdata(pdev);
|
||||||
|
const struct mc13xxx_buttons_platform_data *pdata;
|
||||||
|
|
||||||
|
pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
|
||||||
|
mc13xxx_lock(priv->mc13783);
|
||||||
|
|
||||||
|
if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD3, priv);
|
||||||
|
if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD2, priv);
|
||||||
|
if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
|
||||||
|
mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD1, priv);
|
||||||
|
|
||||||
|
mc13xxx_unlock(priv->mc13783);
|
||||||
|
|
||||||
|
input_unregister_device(priv->pwr);
|
||||||
|
kfree(priv);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct platform_driver mc13783_pwrbutton_driver = {
|
||||||
|
.probe = mc13783_pwrbutton_probe,
|
||||||
|
.remove = __devexit_p(mc13783_pwrbutton_remove),
|
||||||
|
.driver = {
|
||||||
|
.name = "mc13783-pwrbutton",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init mc13783_pwrbutton_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&mc13783_pwrbutton_driver);
|
||||||
|
}
|
||||||
|
module_init(mc13783_pwrbutton_init);
|
||||||
|
|
||||||
|
static void __exit mc13783_pwrbutton_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&mc13783_pwrbutton_driver);
|
||||||
|
}
|
||||||
|
module_exit(mc13783_pwrbutton_exit);
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:mc13783-pwrbutton");
|
||||||
|
MODULE_DESCRIPTION("MC13783 Power Button");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_AUTHOR("Philippe Retornaz");
|
|
@ -35,7 +35,7 @@ MODULE_PARM_DESC(sample_tolerance,
|
||||||
|
|
||||||
struct mc13783_ts_priv {
|
struct mc13783_ts_priv {
|
||||||
struct input_dev *idev;
|
struct input_dev *idev;
|
||||||
struct mc13783 *mc13783;
|
struct mc13xxx *mc13xxx;
|
||||||
struct delayed_work work;
|
struct delayed_work work;
|
||||||
struct workqueue_struct *workq;
|
struct workqueue_struct *workq;
|
||||||
unsigned int sample[4];
|
unsigned int sample[4];
|
||||||
|
@ -45,7 +45,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct mc13783_ts_priv *priv = data;
|
struct mc13783_ts_priv *priv = data;
|
||||||
|
|
||||||
mc13783_irq_ack(priv->mc13783, irq);
|
mc13xxx_irq_ack(priv->mc13xxx, irq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kick off reading coordinates. Note that if work happens already
|
* Kick off reading coordinates. Note that if work happens already
|
||||||
|
@ -121,10 +121,10 @@ static void mc13783_ts_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct mc13783_ts_priv *priv =
|
struct mc13783_ts_priv *priv =
|
||||||
container_of(work, struct mc13783_ts_priv, work.work);
|
container_of(work, struct mc13783_ts_priv, work.work);
|
||||||
unsigned int mode = MC13783_ADC_MODE_TS;
|
unsigned int mode = MC13XXX_ADC_MODE_TS;
|
||||||
unsigned int channel = 12;
|
unsigned int channel = 12;
|
||||||
|
|
||||||
if (mc13783_adc_do_conversion(priv->mc13783,
|
if (mc13xxx_adc_do_conversion(priv->mc13xxx,
|
||||||
mode, channel, priv->sample) == 0)
|
mode, channel, priv->sample) == 0)
|
||||||
mc13783_ts_report_sample(priv);
|
mc13783_ts_report_sample(priv);
|
||||||
}
|
}
|
||||||
|
@ -134,21 +134,21 @@ static int mc13783_ts_open(struct input_dev *dev)
|
||||||
struct mc13783_ts_priv *priv = input_get_drvdata(dev);
|
struct mc13783_ts_priv *priv = input_get_drvdata(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mc13783_lock(priv->mc13783);
|
mc13xxx_lock(priv->mc13xxx);
|
||||||
|
|
||||||
mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS);
|
mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TS);
|
||||||
|
|
||||||
ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
|
ret = mc13xxx_irq_request(priv->mc13xxx, MC13XXX_IRQ_TS,
|
||||||
mc13783_ts_handler, MC13783_TS_NAME, priv);
|
mc13783_ts_handler, MC13783_TS_NAME, priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = mc13783_reg_rmw(priv->mc13783, MC13783_ADC0,
|
ret = mc13xxx_reg_rmw(priv->mc13xxx, MC13XXX_ADC0,
|
||||||
MC13783_ADC0_TSMOD_MASK, MC13783_ADC0_TSMOD0);
|
MC13XXX_ADC0_TSMOD_MASK, MC13XXX_ADC0_TSMOD0);
|
||||||
if (ret)
|
if (ret)
|
||||||
mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv);
|
mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TS, priv);
|
||||||
out:
|
out:
|
||||||
mc13783_unlock(priv->mc13783);
|
mc13xxx_unlock(priv->mc13xxx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,11 +156,11 @@ static void mc13783_ts_close(struct input_dev *dev)
|
||||||
{
|
{
|
||||||
struct mc13783_ts_priv *priv = input_get_drvdata(dev);
|
struct mc13783_ts_priv *priv = input_get_drvdata(dev);
|
||||||
|
|
||||||
mc13783_lock(priv->mc13783);
|
mc13xxx_lock(priv->mc13xxx);
|
||||||
mc13783_reg_rmw(priv->mc13783, MC13783_ADC0,
|
mc13xxx_reg_rmw(priv->mc13xxx, MC13XXX_ADC0,
|
||||||
MC13783_ADC0_TSMOD_MASK, 0);
|
MC13XXX_ADC0_TSMOD_MASK, 0);
|
||||||
mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv);
|
mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TS, priv);
|
||||||
mc13783_unlock(priv->mc13783);
|
mc13xxx_unlock(priv->mc13xxx);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&priv->work);
|
cancel_delayed_work_sync(&priv->work);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
|
||||||
goto err_free_mem;
|
goto err_free_mem;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
|
INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
|
||||||
priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
|
priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
|
||||||
priv->idev = idev;
|
priv->idev = idev;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -107,9 +107,10 @@ static int __devinit asic3_led_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
led->cdev->name = led->name;
|
led->cdev->name = led->name;
|
||||||
led->cdev->default_trigger = led->default_trigger;
|
led->cdev->flags = LED_CORE_SUSPENDRESUME;
|
||||||
led->cdev->brightness_set = brightness_set;
|
led->cdev->brightness_set = brightness_set;
|
||||||
led->cdev->blink_set = blink_set;
|
led->cdev->blink_set = blink_set;
|
||||||
|
led->cdev->default_trigger = led->default_trigger;
|
||||||
|
|
||||||
ret = led_classdev_register(&pdev->dev, led->cdev);
|
ret = led_classdev_register(&pdev->dev, led->cdev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -136,12 +137,44 @@ static int __devexit asic3_led_remove(struct platform_device *pdev)
|
||||||
return mfd_cell_disable(pdev);
|
return mfd_cell_disable(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int asic3_led_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if (cell->suspend)
|
||||||
|
ret = (*cell->suspend)(pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int asic3_led_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if (cell->resume)
|
||||||
|
ret = (*cell->resume)(pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops asic3_led_pm_ops = {
|
||||||
|
.suspend = asic3_led_suspend,
|
||||||
|
.resume = asic3_led_resume,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_driver asic3_led_driver = {
|
static struct platform_driver asic3_led_driver = {
|
||||||
.probe = asic3_led_probe,
|
.probe = asic3_led_probe,
|
||||||
.remove = __devexit_p(asic3_led_remove),
|
.remove = __devexit_p(asic3_led_remove),
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-asic3",
|
.name = "leds-asic3",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.pm = &asic3_led_pm_ops,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/mfd/mc13783.h>
|
#include <linux/mfd/mc13xxx.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
struct mc13783_led {
|
struct mc13783_led {
|
||||||
struct led_classdev cdev;
|
struct led_classdev cdev;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct mc13783 *master;
|
struct mc13xxx *master;
|
||||||
enum led_brightness new_brightness;
|
enum led_brightness new_brightness;
|
||||||
int id;
|
int id;
|
||||||
};
|
};
|
||||||
|
@ -111,11 +111,11 @@ static void mc13783_led_work(struct work_struct *work)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc13783_lock(led->master);
|
mc13xxx_lock(led->master);
|
||||||
|
|
||||||
mc13783_reg_rmw(led->master, reg, mask, value);
|
mc13xxx_reg_rmw(led->master, reg, mask, value);
|
||||||
|
|
||||||
mc13783_unlock(led->master);
|
mc13xxx_unlock(led->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mc13783_led_set(struct led_classdev *led_cdev,
|
static void mc13783_led_set(struct led_classdev *led_cdev,
|
||||||
|
@ -172,23 +172,23 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc13783_lock(led->master);
|
mc13xxx_lock(led->master);
|
||||||
|
|
||||||
ret = mc13783_reg_rmw(led->master, reg, mask << shift,
|
ret = mc13xxx_reg_rmw(led->master, reg, mask << shift,
|
||||||
value << shift);
|
value << shift);
|
||||||
|
|
||||||
mc13783_unlock(led->master);
|
mc13xxx_unlock(led->master);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||||
struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
|
struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int reg = 0;
|
int reg = 0;
|
||||||
|
|
||||||
mc13783_lock(dev);
|
mc13xxx_lock(dev);
|
||||||
|
|
||||||
if (pdata->flags & MC13783_LED_TC1HALF)
|
if (pdata->flags & MC13783_LED_TC1HALF)
|
||||||
reg |= MC13783_LED_C1_TC1HALF_BIT;
|
reg |= MC13783_LED_C1_TC1HALF_BIT;
|
||||||
|
@ -196,7 +196,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
if (pdata->flags & MC13783_LED_SLEWLIMTC)
|
if (pdata->flags & MC13783_LED_SLEWLIMTC)
|
||||||
reg |= MC13783_LED_Cx_SLEWLIM_BIT;
|
reg |= MC13783_LED_Cx_SLEWLIM_BIT;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
if (pdata->flags & MC13783_LED_SLEWLIMBL)
|
if (pdata->flags & MC13783_LED_SLEWLIMBL)
|
||||||
reg |= MC13783_LED_Cx_SLEWLIM_BIT;
|
reg |= MC13783_LED_Cx_SLEWLIM_BIT;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
if (pdata->flags & MC13783_LED_TRIODE_TC1)
|
if (pdata->flags & MC13783_LED_TRIODE_TC1)
|
||||||
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
if (pdata->flags & MC13783_LED_TRIODE_TC2)
|
if (pdata->flags & MC13783_LED_TRIODE_TC2)
|
||||||
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
if (pdata->flags & MC13783_LED_TRIODE_TC3)
|
if (pdata->flags & MC13783_LED_TRIODE_TC3)
|
||||||
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -255,17 +255,17 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
|
||||||
reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
|
reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
|
||||||
MC13783_LED_C0_ABREF;
|
MC13783_LED_C0_ABREF;
|
||||||
|
|
||||||
ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
|
ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mc13783_unlock(dev);
|
mc13xxx_unlock(dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit mc13783_led_probe(struct platform_device *pdev)
|
static int __devinit mc13783_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||||
struct mc13783_led_platform_data *led_cur;
|
struct mc13xxx_led_platform_data *led_cur;
|
||||||
struct mc13783_led *led, *led_dat;
|
struct mc13783_led *led, *led_dat;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
int init_led = 0;
|
int init_led = 0;
|
||||||
|
@ -351,9 +351,9 @@ err_free:
|
||||||
|
|
||||||
static int __devexit mc13783_led_remove(struct platform_device *pdev)
|
static int __devexit mc13783_led_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||||
struct mc13783_led *led = platform_get_drvdata(pdev);
|
struct mc13783_led *led = platform_get_drvdata(pdev);
|
||||||
struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
|
struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < pdata->num_leds; i++) {
|
for (i = 0; i < pdata->num_leds; i++) {
|
||||||
|
@ -361,16 +361,16 @@ static int __devexit mc13783_led_remove(struct platform_device *pdev)
|
||||||
cancel_work_sync(&led[i].work);
|
cancel_work_sync(&led[i].work);
|
||||||
}
|
}
|
||||||
|
|
||||||
mc13783_lock(dev);
|
mc13xxx_lock(dev);
|
||||||
|
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
|
||||||
mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
|
mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
|
||||||
|
|
||||||
mc13783_unlock(dev);
|
mc13xxx_unlock(dev);
|
||||||
|
|
||||||
kfree(led);
|
kfree(led);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -426,7 +426,6 @@ config RADIO_TIMBERDALE
|
||||||
config RADIO_WL1273
|
config RADIO_WL1273
|
||||||
tristate "Texas Instruments WL1273 I2C FM Radio"
|
tristate "Texas Instruments WL1273 I2C FM Radio"
|
||||||
depends on I2C && VIDEO_V4L2
|
depends on I2C && VIDEO_V4L2
|
||||||
select MFD_CORE
|
|
||||||
select MFD_WL1273_CORE
|
select MFD_WL1273_CORE
|
||||||
select FW_LOADER
|
select FW_LOADER
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -2,23 +2,8 @@
|
||||||
# Multifunction miscellaneous devices
|
# Multifunction miscellaneous devices
|
||||||
#
|
#
|
||||||
|
|
||||||
menuconfig MFD_SUPPORT
|
if HAS_IOMEM
|
||||||
bool "Multifunction device drivers"
|
menu "Multifunction device drivers"
|
||||||
depends on HAS_IOMEM
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Multifunction devices embed several functions (e.g. GPIOs,
|
|
||||||
touchscreens, keyboards, current regulators, power management chips,
|
|
||||||
etc...) in one single integrated circuit. They usually talk to the
|
|
||||||
main CPU through one or more IRQ lines and low speed data busses (SPI,
|
|
||||||
I2C, etc..). They appear as one single device to the main system
|
|
||||||
through the data bus and the MFD framework allows for sub devices
|
|
||||||
(a.k.a. functions) to appear as discrete platform devices.
|
|
||||||
MFDs are typically found on embedded platforms.
|
|
||||||
|
|
||||||
This option alone does not add any kernel code.
|
|
||||||
|
|
||||||
if MFD_SUPPORT
|
|
||||||
|
|
||||||
config MFD_CORE
|
config MFD_CORE
|
||||||
tristate
|
tristate
|
||||||
|
@ -390,6 +375,7 @@ config MFD_WM8400
|
||||||
tristate "Support Wolfson Microelectronics WM8400"
|
tristate "Support Wolfson Microelectronics WM8400"
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
select REGMAP_I2C
|
||||||
help
|
help
|
||||||
Support for the Wolfson Microelecronics WM8400 PMIC and audio
|
Support for the Wolfson Microelecronics WM8400 PMIC and audio
|
||||||
CODEC. This driver provides common support for accessing
|
CODEC. This driver provides common support for accessing
|
||||||
|
@ -503,6 +489,7 @@ config MFD_WM8994
|
||||||
config MFD_PCF50633
|
config MFD_PCF50633
|
||||||
tristate "Support for NXP PCF50633"
|
tristate "Support for NXP PCF50633"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
select REGMAP_I2C
|
||||||
help
|
help
|
||||||
Say yes here if you have NXP PCF50633 chip on your board.
|
Say yes here if you have NXP PCF50633 chip on your board.
|
||||||
This core driver provides register access and IRQ handling
|
This core driver provides register access and IRQ handling
|
||||||
|
@ -579,6 +566,23 @@ config EZX_PCAP
|
||||||
This enables the PCAP ASIC present on EZX Phones. This is
|
This enables the PCAP ASIC present on EZX Phones. This is
|
||||||
needed for MMC, TouchScreen, Sound, USB, etc..
|
needed for MMC, TouchScreen, Sound, USB, etc..
|
||||||
|
|
||||||
|
config AB5500_CORE
|
||||||
|
bool "ST-Ericsson AB5500 Mixed Signal Power Management chip"
|
||||||
|
depends on ABX500_CORE && MFD_DB5500_PRCMU
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
Select this option to enable access to AB5500 power management
|
||||||
|
chip. This connects to the db5500 chip via the I2C bus via PRCMU.
|
||||||
|
This chip embeds various other multimedia funtionalities as well.
|
||||||
|
|
||||||
|
config AB5500_DEBUG
|
||||||
|
bool "Enable debug info via debugfs"
|
||||||
|
depends on AB5500_CORE && DEBUG_FS
|
||||||
|
default y if DEBUG_FS
|
||||||
|
help
|
||||||
|
Select this option if you want debug information from the AB5500
|
||||||
|
using the debug filesystem, debugfs.
|
||||||
|
|
||||||
config AB8500_CORE
|
config AB8500_CORE
|
||||||
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
|
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
|
||||||
depends on GENERIC_HARDIRQS && ABX500_CORE
|
depends on GENERIC_HARDIRQS && ABX500_CORE
|
||||||
|
@ -615,20 +619,6 @@ config AB8500_GPADC
|
||||||
help
|
help
|
||||||
AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage
|
AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage
|
||||||
|
|
||||||
config AB3550_CORE
|
|
||||||
bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions"
|
|
||||||
select MFD_CORE
|
|
||||||
depends on I2C=y && GENERIC_HARDIRQS && ABX500_CORE
|
|
||||||
help
|
|
||||||
Select this to enable the AB3550 Mixed Signal IC core
|
|
||||||
functionality. This connects to a AB3550 on the I2C bus
|
|
||||||
and expose a number of symbols needed for dependent devices
|
|
||||||
to read and write registers and subscribe to events from
|
|
||||||
this multi-functional IC. This is needed to use other features
|
|
||||||
of the AB3550 such as battery-backed RTC, charging control,
|
|
||||||
LEDs, vibrator, system power and temperature, power management
|
|
||||||
and ALSA sound.
|
|
||||||
|
|
||||||
config MFD_DB8500_PRCMU
|
config MFD_DB8500_PRCMU
|
||||||
bool "ST-Ericsson DB8500 Power Reset Control Management Unit"
|
bool "ST-Ericsson DB8500 Power Reset Control Management Unit"
|
||||||
depends on UX500_SOC_DB8500
|
depends on UX500_SOC_DB8500
|
||||||
|
@ -773,7 +763,17 @@ config MFD_AAT2870_CORE
|
||||||
additional drivers must be enabled in order to use the
|
additional drivers must be enabled in order to use the
|
||||||
functionality of the device.
|
functionality of the device.
|
||||||
|
|
||||||
endif # MFD_SUPPORT
|
config MFD_INTEL_MSIC
|
||||||
|
bool "Support for Intel MSIC"
|
||||||
|
depends on INTEL_SCU_IPC
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
Select this option to enable access to Intel MSIC (Avatele
|
||||||
|
Passage) chip. This chip embeds audio, battery, GPIO, etc.
|
||||||
|
devices used in Intel Medfield platforms.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
endif
|
||||||
|
|
||||||
menu "Multimedia Capabilities Port drivers"
|
menu "Multimedia Capabilities Port drivers"
|
||||||
depends on ARCH_SA1100
|
depends on ARCH_SA1100
|
||||||
|
|
|
@ -79,7 +79,8 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
|
||||||
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
|
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
|
||||||
obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
|
obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
|
||||||
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
|
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
|
||||||
obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
|
obj-$(CONFIG_AB5500_CORE) += ab5500-core.o
|
||||||
|
obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o
|
||||||
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
|
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
|
||||||
obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
|
obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
|
||||||
obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
|
obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
|
||||||
|
@ -102,3 +103,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
|
||||||
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
|
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
|
||||||
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
|
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
|
||||||
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
|
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
|
||||||
|
obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
|
||||||
|
|
|
@ -295,7 +295,7 @@ static ssize_t aat2870_reg_write_file(struct file *file,
|
||||||
{
|
{
|
||||||
struct aat2870_data *aat2870 = file->private_data;
|
struct aat2870_data *aat2870 = file->private_data;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int buf_size;
|
ssize_t buf_size;
|
||||||
char *start = buf;
|
char *start = buf;
|
||||||
unsigned long addr, val;
|
unsigned long addr, val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -809,7 +809,7 @@ struct ab_family_id {
|
||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ab_family_id ids[] __devinitdata = {
|
static const struct ab_family_id ids[] __devinitconst = {
|
||||||
/* AB3100 */
|
/* AB3100 */
|
||||||
{
|
{
|
||||||
.id = 0xc0,
|
.id = 0xc0,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 ST-Ericsson
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
* Shared definitions and data structures for the AB5500 MFD driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Read/write operation values. */
|
||||||
|
#define AB5500_PERM_RD (0x01)
|
||||||
|
#define AB5500_PERM_WR (0x02)
|
||||||
|
|
||||||
|
/* Read/write permissions. */
|
||||||
|
#define AB5500_PERM_RO (AB5500_PERM_RD)
|
||||||
|
#define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR)
|
||||||
|
|
||||||
|
#define AB5500_MASK_BASE (0x60)
|
||||||
|
#define AB5500_MASK_END (0x79)
|
||||||
|
#define AB5500_CHIP_ID (0x20)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ab5500_reg_range
|
||||||
|
* @first: the first address of the range
|
||||||
|
* @last: the last address of the range
|
||||||
|
* @perm: access permissions for the range
|
||||||
|
*/
|
||||||
|
struct ab5500_reg_range {
|
||||||
|
u8 first;
|
||||||
|
u8 last;
|
||||||
|
u8 perm;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ab5500_i2c_ranges
|
||||||
|
* @count: the number of ranges in the list
|
||||||
|
* @range: the list of register ranges
|
||||||
|
*/
|
||||||
|
struct ab5500_i2c_ranges {
|
||||||
|
u8 nranges;
|
||||||
|
u8 bankid;
|
||||||
|
const struct ab5500_reg_range *range;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ab5500_i2c_banks
|
||||||
|
* @count: the number of ranges in the list
|
||||||
|
* @range: the list of register ranges
|
||||||
|
*/
|
||||||
|
struct ab5500_i2c_banks {
|
||||||
|
u8 nbanks;
|
||||||
|
const struct ab5500_i2c_ranges *bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ab5500_bank
|
||||||
|
* @slave_addr: I2C slave_addr found in AB5500 specification
|
||||||
|
* @name: Documentation name of the bank. For reference
|
||||||
|
*/
|
||||||
|
struct ab5500_bank {
|
||||||
|
u8 slave_addr;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = {
|
||||||
|
[AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
|
||||||
|
AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"},
|
||||||
|
[AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
|
||||||
|
AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"},
|
||||||
|
[AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"},
|
||||||
|
[AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"},
|
||||||
|
[AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"},
|
||||||
|
[AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"},
|
||||||
|
[AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"},
|
||||||
|
[AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"},
|
||||||
|
[AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"},
|
||||||
|
[AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"},
|
||||||
|
[AB5500_BANK_FG_BATTCOM_ACC] = {
|
||||||
|
AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"},
|
||||||
|
[AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"},
|
||||||
|
[AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"},
|
||||||
|
[AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"},
|
||||||
|
[AB5500_BANK_AUDIO_HEADSETUSB] = {
|
||||||
|
AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"},
|
||||||
|
};
|
||||||
|
|
||||||
|
int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg,
|
||||||
|
u8 *value);
|
||||||
|
int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank,
|
||||||
|
u8 reg, u8 bitmask, u8 bitvalues);
|
|
@ -0,0 +1,806 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 ST-Ericsson
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
* Debugfs support for the AB5500 MFD driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/mfd/ab5500/ab5500.h>
|
||||||
|
#include <linux/mfd/abx500.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
#include "ab5500-core.h"
|
||||||
|
#include "ab5500-debugfs.h"
|
||||||
|
|
||||||
|
static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = {
|
||||||
|
[AB5500_BANK_LED] = {
|
||||||
|
.bankid = AB5500_BANK_LED,
|
||||||
|
.nranges = 1,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x0C,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_ADC] = {
|
||||||
|
.bankid = AB5500_BANK_ADC,
|
||||||
|
.nranges = 6,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x1F,
|
||||||
|
.last = 0x22,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x23,
|
||||||
|
.last = 0x24,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x26,
|
||||||
|
.last = 0x2D,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x2F,
|
||||||
|
.last = 0x34,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x37,
|
||||||
|
.last = 0x57,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x58,
|
||||||
|
.last = 0x58,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_RTC] = {
|
||||||
|
.bankid = AB5500_BANK_RTC,
|
||||||
|
.nranges = 2,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x04,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x06,
|
||||||
|
.last = 0x0C,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_STARTUP] = {
|
||||||
|
.bankid = AB5500_BANK_STARTUP,
|
||||||
|
.nranges = 12,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x01,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x1F,
|
||||||
|
.last = 0x1F,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x2E,
|
||||||
|
.last = 0x2E,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x2F,
|
||||||
|
.last = 0x30,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x50,
|
||||||
|
.last = 0x51,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x60,
|
||||||
|
.last = 0x61,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x66,
|
||||||
|
.last = 0x8A,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x8C,
|
||||||
|
.last = 0x96,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xAA,
|
||||||
|
.last = 0xB4,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xB7,
|
||||||
|
.last = 0xBF,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xC1,
|
||||||
|
.last = 0xCA,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xD3,
|
||||||
|
.last = 0xE0,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_DBI_ECI] = {
|
||||||
|
.bankid = AB5500_BANK_DBI_ECI,
|
||||||
|
.nranges = 3,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x07,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x10,
|
||||||
|
.last = 0x10,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x13,
|
||||||
|
.last = 0x13,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_CHG] = {
|
||||||
|
.bankid = AB5500_BANK_CHG,
|
||||||
|
.nranges = 2,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x11,
|
||||||
|
.last = 0x11,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x12,
|
||||||
|
.last = 0x1B,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_FG_BATTCOM_ACC] = {
|
||||||
|
.bankid = AB5500_BANK_FG_BATTCOM_ACC,
|
||||||
|
.nranges = 2,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x0B,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x0C,
|
||||||
|
.last = 0x10,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_USB] = {
|
||||||
|
.bankid = AB5500_BANK_USB,
|
||||||
|
.nranges = 12,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x01,
|
||||||
|
.last = 0x01,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x80,
|
||||||
|
.last = 0x83,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x87,
|
||||||
|
.last = 0x8A,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x8B,
|
||||||
|
.last = 0x8B,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x91,
|
||||||
|
.last = 0x92,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x93,
|
||||||
|
.last = 0x93,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x94,
|
||||||
|
.last = 0x94,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xA8,
|
||||||
|
.last = 0xB0,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xB2,
|
||||||
|
.last = 0xB2,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xB4,
|
||||||
|
.last = 0xBC,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xBF,
|
||||||
|
.last = 0xBF,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xC1,
|
||||||
|
.last = 0xC5,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_IT] = {
|
||||||
|
.bankid = AB5500_BANK_IT,
|
||||||
|
.nranges = 4,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x02,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x20,
|
||||||
|
.last = 0x36,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x40,
|
||||||
|
.last = 0x56,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x60,
|
||||||
|
.last = 0x76,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
|
||||||
|
.bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST,
|
||||||
|
.nranges = 7,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x02,
|
||||||
|
.last = 0x02,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x12,
|
||||||
|
.last = 0x12,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x30,
|
||||||
|
.last = 0x34,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x40,
|
||||||
|
.last = 0x44,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x50,
|
||||||
|
.last = 0x54,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x60,
|
||||||
|
.last = 0x64,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x70,
|
||||||
|
.last = 0x74,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
|
||||||
|
.bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
|
||||||
|
.nranges = 13,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x01,
|
||||||
|
.last = 0x01,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x02,
|
||||||
|
.last = 0x02,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x0D,
|
||||||
|
.last = 0x0F,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x1C,
|
||||||
|
.last = 0x1C,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x1E,
|
||||||
|
.last = 0x1E,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x20,
|
||||||
|
.last = 0x21,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x25,
|
||||||
|
.last = 0x25,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x28,
|
||||||
|
.last = 0x2A,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x30,
|
||||||
|
.last = 0x33,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x40,
|
||||||
|
.last = 0x43,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x50,
|
||||||
|
.last = 0x53,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x60,
|
||||||
|
.last = 0x63,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x70,
|
||||||
|
.last = 0x73,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_VIBRA] = {
|
||||||
|
.bankid = AB5500_BANK_VIBRA,
|
||||||
|
.nranges = 2,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x10,
|
||||||
|
.last = 0x13,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xFE,
|
||||||
|
.last = 0xFE,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_AUDIO_HEADSETUSB] = {
|
||||||
|
.bankid = AB5500_BANK_AUDIO_HEADSETUSB,
|
||||||
|
.nranges = 2,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x48,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0xEB,
|
||||||
|
.last = 0xFB,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_SIM_USBSIM] = {
|
||||||
|
.bankid = AB5500_BANK_SIM_USBSIM,
|
||||||
|
.nranges = 1,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x13,
|
||||||
|
.last = 0x19,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[AB5500_BANK_VDENC] = {
|
||||||
|
.bankid = AB5500_BANK_VDENC,
|
||||||
|
.nranges = 12,
|
||||||
|
.range = (struct ab5500_reg_range[]) {
|
||||||
|
{
|
||||||
|
.first = 0x00,
|
||||||
|
.last = 0x08,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x09,
|
||||||
|
.last = 0x09,
|
||||||
|
.perm = AB5500_PERM_RO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x0A,
|
||||||
|
.last = 0x12,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x15,
|
||||||
|
.last = 0x19,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x1B,
|
||||||
|
.last = 0x21,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x27,
|
||||||
|
.last = 0x2C,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x41,
|
||||||
|
.last = 0x41,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x45,
|
||||||
|
.last = 0x5B,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x5D,
|
||||||
|
.last = 0x5D,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x69,
|
||||||
|
.last = 0x69,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x6C,
|
||||||
|
.last = 0x6D,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first = 0x80,
|
||||||
|
.last = 0x81,
|
||||||
|
.perm = AB5500_PERM_RW,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ab5500_registers_print(struct seq_file *s, void *p)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = s->private;
|
||||||
|
unsigned int i;
|
||||||
|
u8 bank = (u8)ab->debug_bank;
|
||||||
|
|
||||||
|
seq_printf(s, "ab5500 register values:\n");
|
||||||
|
for (bank = 0; bank < AB5500_NUM_BANKS; bank++) {
|
||||||
|
seq_printf(s, " bank %u, %s (0x%x):\n", bank,
|
||||||
|
bankinfo[bank].name,
|
||||||
|
bankinfo[bank].slave_addr);
|
||||||
|
for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) {
|
||||||
|
u8 reg;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
for (reg = ab5500_reg_ranges[bank].range[i].first;
|
||||||
|
reg <= ab5500_reg_ranges[bank].range[i].last;
|
||||||
|
reg++) {
|
||||||
|
u8 value;
|
||||||
|
|
||||||
|
err = ab5500_get_register_interruptible_raw(ab,
|
||||||
|
bank, reg,
|
||||||
|
&value);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(ab->dev, "get_reg failed %d"
|
||||||
|
"bank 0x%x reg 0x%x\n",
|
||||||
|
err, bank, reg);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n",
|
||||||
|
bank, reg, value);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(ab->dev,
|
||||||
|
"seq_printf overflow\n");
|
||||||
|
/*
|
||||||
|
* Error is not returned here since
|
||||||
|
* the output is wanted in any case
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_registers_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, ab5500_registers_print, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations ab5500_registers_fops = {
|
||||||
|
.open = ab5500_registers_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ab5500_bank_print(struct seq_file *s, void *p)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = s->private;
|
||||||
|
|
||||||
|
seq_printf(s, "%d\n", ab->debug_bank);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_bank_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, ab5500_bank_print, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ab5500_bank_write(struct file *file,
|
||||||
|
const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
|
||||||
|
char buf[32];
|
||||||
|
int buf_size;
|
||||||
|
unsigned long user_bank;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Get userspace string and assure termination */
|
||||||
|
buf_size = min(count, (sizeof(buf) - 1));
|
||||||
|
if (copy_from_user(buf, user_buf, buf_size))
|
||||||
|
return -EFAULT;
|
||||||
|
buf[buf_size] = 0;
|
||||||
|
|
||||||
|
err = strict_strtoul(buf, 0, &user_bank);
|
||||||
|
if (err)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (user_bank >= AB5500_NUM_BANKS) {
|
||||||
|
dev_err(ab->dev,
|
||||||
|
"debugfs error input > number of banks\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ab->debug_bank = user_bank;
|
||||||
|
|
||||||
|
return buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_address_print(struct seq_file *s, void *p)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = s->private;
|
||||||
|
|
||||||
|
seq_printf(s, "0x%02X\n", ab->debug_address);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_address_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, ab5500_address_print, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ab5500_address_write(struct file *file,
|
||||||
|
const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
|
||||||
|
char buf[32];
|
||||||
|
int buf_size;
|
||||||
|
unsigned long user_address;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Get userspace string and assure termination */
|
||||||
|
buf_size = min(count, (sizeof(buf) - 1));
|
||||||
|
if (copy_from_user(buf, user_buf, buf_size))
|
||||||
|
return -EFAULT;
|
||||||
|
buf[buf_size] = 0;
|
||||||
|
|
||||||
|
err = strict_strtoul(buf, 0, &user_address);
|
||||||
|
if (err)
|
||||||
|
return -EINVAL;
|
||||||
|
if (user_address > 0xff) {
|
||||||
|
dev_err(ab->dev,
|
||||||
|
"debugfs error input > 0xff\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ab->debug_address = user_address;
|
||||||
|
return buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_val_print(struct seq_file *s, void *p)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = s->private;
|
||||||
|
int err;
|
||||||
|
u8 regvalue;
|
||||||
|
|
||||||
|
err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
|
||||||
|
(u8)ab->debug_address, ®value);
|
||||||
|
if (err) {
|
||||||
|
dev_err(ab->dev, "get_reg failed %d, bank 0x%x"
|
||||||
|
", reg 0x%x\n", err, ab->debug_bank,
|
||||||
|
ab->debug_address);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
seq_printf(s, "0x%02X\n", regvalue);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ab5500_val_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, ab5500_val_print, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ab5500_val_write(struct file *file,
|
||||||
|
const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
|
||||||
|
char buf[32];
|
||||||
|
int buf_size;
|
||||||
|
unsigned long user_val;
|
||||||
|
int err;
|
||||||
|
u8 regvalue;
|
||||||
|
|
||||||
|
/* Get userspace string and assure termination */
|
||||||
|
buf_size = min(count, (sizeof(buf)-1));
|
||||||
|
if (copy_from_user(buf, user_buf, buf_size))
|
||||||
|
return -EFAULT;
|
||||||
|
buf[buf_size] = 0;
|
||||||
|
|
||||||
|
err = strict_strtoul(buf, 0, &user_val);
|
||||||
|
if (err)
|
||||||
|
return -EINVAL;
|
||||||
|
if (user_val > 0xff) {
|
||||||
|
dev_err(ab->dev,
|
||||||
|
"debugfs error input > 0xff\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
err = ab5500_mask_and_set_register_interruptible_raw(
|
||||||
|
ab, (u8)ab->debug_bank,
|
||||||
|
(u8)ab->debug_address, 0xFF, (u8)user_val);
|
||||||
|
if (err)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
|
||||||
|
(u8)ab->debug_address, ®value);
|
||||||
|
if (err)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations ab5500_bank_fops = {
|
||||||
|
.open = ab5500_bank_open,
|
||||||
|
.write = ab5500_bank_write,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations ab5500_address_fops = {
|
||||||
|
.open = ab5500_address_open,
|
||||||
|
.write = ab5500_address_write,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations ab5500_val_fops = {
|
||||||
|
.open = ab5500_val_open,
|
||||||
|
.write = ab5500_val_write,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dentry *ab5500_dir;
|
||||||
|
static struct dentry *ab5500_reg_file;
|
||||||
|
static struct dentry *ab5500_bank_file;
|
||||||
|
static struct dentry *ab5500_address_file;
|
||||||
|
static struct dentry *ab5500_val_file;
|
||||||
|
|
||||||
|
void __init ab5500_setup_debugfs(struct ab5500 *ab)
|
||||||
|
{
|
||||||
|
ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP;
|
||||||
|
ab->debug_address = AB5500_CHIP_ID;
|
||||||
|
|
||||||
|
ab5500_dir = debugfs_create_dir("ab5500", NULL);
|
||||||
|
if (!ab5500_dir)
|
||||||
|
goto exit_no_debugfs;
|
||||||
|
|
||||||
|
ab5500_reg_file = debugfs_create_file("all-bank-registers",
|
||||||
|
S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops);
|
||||||
|
if (!ab5500_reg_file)
|
||||||
|
goto exit_destroy_dir;
|
||||||
|
|
||||||
|
ab5500_bank_file = debugfs_create_file("register-bank",
|
||||||
|
(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops);
|
||||||
|
if (!ab5500_bank_file)
|
||||||
|
goto exit_destroy_reg;
|
||||||
|
|
||||||
|
ab5500_address_file = debugfs_create_file("register-address",
|
||||||
|
(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops);
|
||||||
|
if (!ab5500_address_file)
|
||||||
|
goto exit_destroy_bank;
|
||||||
|
|
||||||
|
ab5500_val_file = debugfs_create_file("register-value",
|
||||||
|
(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops);
|
||||||
|
if (!ab5500_val_file)
|
||||||
|
goto exit_destroy_address;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_destroy_address:
|
||||||
|
debugfs_remove(ab5500_address_file);
|
||||||
|
exit_destroy_bank:
|
||||||
|
debugfs_remove(ab5500_bank_file);
|
||||||
|
exit_destroy_reg:
|
||||||
|
debugfs_remove(ab5500_reg_file);
|
||||||
|
exit_destroy_dir:
|
||||||
|
debugfs_remove(ab5500_dir);
|
||||||
|
exit_no_debugfs:
|
||||||
|
dev_err(ab->dev, "failed to create debugfs entries.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __exit ab5500_remove_debugfs(void)
|
||||||
|
{
|
||||||
|
debugfs_remove(ab5500_val_file);
|
||||||
|
debugfs_remove(ab5500_address_file);
|
||||||
|
debugfs_remove(ab5500_bank_file);
|
||||||
|
debugfs_remove(ab5500_reg_file);
|
||||||
|
debugfs_remove(ab5500_dir);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 ST-Ericsson
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
* Debugfs interface to the AB5500 core driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
|
||||||
|
void ab5500_setup_debugfs(struct ab5500 *ab);
|
||||||
|
void ab5500_remove_debugfs(void);
|
||||||
|
|
||||||
|
#else /* !CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
static inline void ab5500_setup_debugfs(struct ab5500 *ab)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ab5500_remove_debugfs(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -92,6 +92,8 @@
|
||||||
#define AB8500_REV_REG 0x80
|
#define AB8500_REV_REG 0x80
|
||||||
#define AB8500_SWITCH_OFF_STATUS 0x00
|
#define AB8500_SWITCH_OFF_STATUS 0x00
|
||||||
|
|
||||||
|
#define AB8500_TURN_ON_STATUS 0x00
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
|
* Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
|
||||||
* numbers are indexed into this array with (num / 8).
|
* numbers are indexed into this array with (num / 8).
|
||||||
|
@ -293,6 +295,7 @@ static struct irq_chip ab8500_irq_chip = {
|
||||||
.irq_bus_lock = ab8500_irq_lock,
|
.irq_bus_lock = ab8500_irq_lock,
|
||||||
.irq_bus_sync_unlock = ab8500_irq_sync_unlock,
|
.irq_bus_sync_unlock = ab8500_irq_sync_unlock,
|
||||||
.irq_mask = ab8500_irq_mask,
|
.irq_mask = ab8500_irq_mask,
|
||||||
|
.irq_disable = ab8500_irq_mask,
|
||||||
.irq_unmask = ab8500_irq_unmask,
|
.irq_unmask = ab8500_irq_unmask,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -811,12 +814,40 @@ static ssize_t show_switch_off_status(struct device *dev,
|
||||||
return sprintf(buf, "%#x\n", value);
|
return sprintf(buf, "%#x\n", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ab8500 has turned on due to (TURN_ON_STATUS):
|
||||||
|
* 0x01 PORnVbat
|
||||||
|
* 0x02 PonKey1dbF
|
||||||
|
* 0x04 PonKey2dbF
|
||||||
|
* 0x08 RTCAlarm
|
||||||
|
* 0x10 MainChDet
|
||||||
|
* 0x20 VbusDet
|
||||||
|
* 0x40 UsbIDDetect
|
||||||
|
* 0x80 Reserved
|
||||||
|
*/
|
||||||
|
static ssize_t show_turn_on_status(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 value;
|
||||||
|
struct ab8500 *ab8500;
|
||||||
|
|
||||||
|
ab8500 = dev_get_drvdata(dev);
|
||||||
|
ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
|
||||||
|
AB8500_TURN_ON_STATUS, &value);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return sprintf(buf, "%#x\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
|
static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
|
||||||
static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
|
static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
|
||||||
|
static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL);
|
||||||
|
|
||||||
static struct attribute *ab8500_sysfs_entries[] = {
|
static struct attribute *ab8500_sysfs_entries[] = {
|
||||||
&dev_attr_chip_id.attr,
|
&dev_attr_chip_id.attr,
|
||||||
&dev_attr_switch_off_status.attr,
|
&dev_attr_switch_off_status.attr,
|
||||||
|
&dev_attr_turn_on_status.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -843,11 +874,11 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case AB8500_CUTEARLY:
|
|
||||||
case AB8500_CUT1P0:
|
case AB8500_CUT1P0:
|
||||||
case AB8500_CUT1P1:
|
case AB8500_CUT1P1:
|
||||||
case AB8500_CUT2P0:
|
case AB8500_CUT2P0:
|
||||||
case AB8500_CUT3P0:
|
case AB8500_CUT3P0:
|
||||||
|
case AB8500_CUT3P3:
|
||||||
dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
|
dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -143,12 +143,15 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ab8500_gpadc_get);
|
EXPORT_SYMBOL(ab8500_gpadc_get);
|
||||||
|
|
||||||
static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
|
/**
|
||||||
|
* ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
|
||||||
|
*/
|
||||||
|
int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
|
||||||
int ad_value)
|
int ad_value)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
switch (input) {
|
switch (channel) {
|
||||||
case MAIN_CHARGER_V:
|
case MAIN_CHARGER_V:
|
||||||
/* For some reason we don't have calibrated data */
|
/* For some reason we don't have calibrated data */
|
||||||
if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
|
if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
|
||||||
|
@ -232,18 +235,46 @@ static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ab8500_gpadc_convert() - gpadc conversion
|
* ab8500_gpadc_convert() - gpadc conversion
|
||||||
* @input: analog input to be converted to digital data
|
* @channel: analog channel to be converted to digital data
|
||||||
*
|
*
|
||||||
* This function converts the selected analog i/p to digital
|
* This function converts the selected analog i/p to digital
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
|
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel)
|
||||||
|
{
|
||||||
|
int ad_value;
|
||||||
|
int voltage;
|
||||||
|
|
||||||
|
ad_value = ab8500_gpadc_read_raw(gpadc, channel);
|
||||||
|
if (ad_value < 0) {
|
||||||
|
dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel);
|
||||||
|
return ad_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);
|
||||||
|
|
||||||
|
if (voltage < 0)
|
||||||
|
dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
|
||||||
|
" %d AD: 0x%x\n", channel, ad_value);
|
||||||
|
|
||||||
|
return voltage;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ab8500_gpadc_convert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ab8500_gpadc_read_raw() - gpadc read
|
||||||
|
* @channel: analog channel to be read
|
||||||
|
*
|
||||||
|
* This function obtains the raw ADC value, this then needs
|
||||||
|
* to be converted by calling ab8500_gpadc_ad_to_voltage()
|
||||||
|
*/
|
||||||
|
int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u16 data = 0;
|
|
||||||
int looplimit = 0;
|
int looplimit = 0;
|
||||||
u8 val, low_data, high_data;
|
u8 val, low_data, high_data;
|
||||||
|
|
||||||
|
@ -278,9 +309,9 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the input source and set average samples to 16 */
|
/* Select the channel source and set average samples to 16 */
|
||||||
ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
|
ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
|
||||||
AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
|
AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(gpadc->dev,
|
dev_err(gpadc->dev,
|
||||||
"gpadc_conversion: set avg samples failed\n");
|
"gpadc_conversion: set avg samples failed\n");
|
||||||
|
@ -292,7 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
|
||||||
* charging current sense if it needed, ABB 3.0 needs some special
|
* charging current sense if it needed, ABB 3.0 needs some special
|
||||||
* treatment too.
|
* treatment too.
|
||||||
*/
|
*/
|
||||||
switch (input) {
|
switch (channel) {
|
||||||
case MAIN_CHARGER_C:
|
case MAIN_CHARGER_C:
|
||||||
case USB_CHARGER_C:
|
case USB_CHARGER_C:
|
||||||
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
|
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
|
||||||
|
@ -359,7 +390,6 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (high_data << 8) | low_data;
|
|
||||||
/* Disable GPADC */
|
/* Disable GPADC */
|
||||||
ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
|
ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
|
||||||
AB8500_GPADC_CTRL1_REG, DIS_GPADC);
|
AB8500_GPADC_CTRL1_REG, DIS_GPADC);
|
||||||
|
@ -370,8 +400,8 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
|
||||||
/* Disable VTVout LDO this is required for GPADC */
|
/* Disable VTVout LDO this is required for GPADC */
|
||||||
regulator_disable(gpadc->regu);
|
regulator_disable(gpadc->regu);
|
||||||
mutex_unlock(&gpadc->ab8500_gpadc_lock);
|
mutex_unlock(&gpadc->ab8500_gpadc_lock);
|
||||||
ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
|
|
||||||
return ret;
|
return (high_data << 8) | low_data;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/*
|
/*
|
||||||
|
@ -385,10 +415,10 @@ out:
|
||||||
regulator_disable(gpadc->regu);
|
regulator_disable(gpadc->regu);
|
||||||
mutex_unlock(&gpadc->ab8500_gpadc_lock);
|
mutex_unlock(&gpadc->ab8500_gpadc_lock);
|
||||||
dev_err(gpadc->dev,
|
dev_err(gpadc->dev,
|
||||||
"gpadc_conversion: Failed to AD convert channel %d\n", input);
|
"gpadc_conversion: Failed to AD convert channel %d\n", channel);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ab8500_gpadc_convert);
|
EXPORT_SYMBOL(ab8500_gpadc_read_raw);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
|
* ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
|
||||||
|
|
|
@ -584,7 +584,7 @@ static int asic3_gpio_remove(struct platform_device *pdev)
|
||||||
return gpiochip_remove(&asic->gpio);
|
return gpiochip_remove(&asic->gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
|
static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 cdex;
|
u32 cdex;
|
||||||
|
@ -596,8 +596,6 @@ static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
|
||||||
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
|
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&asic->lock, flags);
|
spin_unlock_irqrestore(&asic->lock, flags);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
|
static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
|
||||||
|
@ -779,6 +777,8 @@ static struct mfd_cell asic3_cell_mmc = {
|
||||||
.name = "tmio-mmc",
|
.name = "tmio-mmc",
|
||||||
.enable = asic3_mmc_enable,
|
.enable = asic3_mmc_enable,
|
||||||
.disable = asic3_mmc_disable,
|
.disable = asic3_mmc_disable,
|
||||||
|
.suspend = asic3_mmc_disable,
|
||||||
|
.resume = asic3_mmc_enable,
|
||||||
.platform_data = &asic3_mmc_data,
|
.platform_data = &asic3_mmc_data,
|
||||||
.pdata_size = sizeof(asic3_mmc_data),
|
.pdata_size = sizeof(asic3_mmc_data),
|
||||||
.num_resources = ARRAY_SIZE(asic3_mmc_resources),
|
.num_resources = ARRAY_SIZE(asic3_mmc_resources),
|
||||||
|
@ -811,24 +811,43 @@ static int asic3_leds_disable(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int asic3_leds_suspend(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||||
|
struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
|
||||||
|
while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0)
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
|
asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = {
|
static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.name = "leds-asic3",
|
.name = "leds-asic3",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.enable = asic3_leds_enable,
|
.enable = asic3_leds_enable,
|
||||||
.disable = asic3_leds_disable,
|
.disable = asic3_leds_disable,
|
||||||
|
.suspend = asic3_leds_suspend,
|
||||||
|
.resume = asic3_leds_enable,
|
||||||
},
|
},
|
||||||
[1] = {
|
[1] = {
|
||||||
.name = "leds-asic3",
|
.name = "leds-asic3",
|
||||||
.id = 1,
|
.id = 1,
|
||||||
.enable = asic3_leds_enable,
|
.enable = asic3_leds_enable,
|
||||||
.disable = asic3_leds_disable,
|
.disable = asic3_leds_disable,
|
||||||
|
.suspend = asic3_leds_suspend,
|
||||||
|
.resume = asic3_leds_enable,
|
||||||
},
|
},
|
||||||
[2] = {
|
[2] = {
|
||||||
.name = "leds-asic3",
|
.name = "leds-asic3",
|
||||||
.id = 2,
|
.id = 2,
|
||||||
.enable = asic3_leds_enable,
|
.enable = asic3_leds_enable,
|
||||||
.disable = asic3_leds_disable,
|
.disable = asic3_leds_disable,
|
||||||
|
.suspend = asic3_leds_suspend,
|
||||||
|
.resume = asic3_leds_enable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -949,6 +968,7 @@ static int __init asic3_probe(struct platform_device *pdev)
|
||||||
goto out_unmap;
|
goto out_unmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asic->gpio.label = "asic3";
|
||||||
asic->gpio.base = pdata->gpio_base;
|
asic->gpio.base = pdata->gpio_base;
|
||||||
asic->gpio.ngpio = ASIC3_NUM_GPIOS;
|
asic->gpio.ngpio = ASIC3_NUM_GPIOS;
|
||||||
asic->gpio.get = asic3_gpio_get;
|
asic->gpio.get = asic3_gpio_get;
|
||||||
|
|
|
@ -523,7 +523,7 @@ static int __devinit da903x_probe(struct i2c_client *client,
|
||||||
chip->ops->read_events(chip, &tmp);
|
chip->ops->read_events(chip, &tmp);
|
||||||
|
|
||||||
ret = request_irq(client->irq, da903x_irq_handler,
|
ret = request_irq(client->irq, da903x_irq_handler,
|
||||||
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
|
IRQF_TRIGGER_FALLING,
|
||||||
"da903x", chip);
|
"da903x", chip);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&client->dev, "failed to request irq %d\n",
|
dev_err(&client->dev, "failed to request irq %d\n",
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mfd/db5500-prcmu.h>
|
#include <linux/mfd/dbx500-prcmu.h>
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/irqs.h>
|
#include <mach/irqs.h>
|
||||||
#include <mach/db5500-regs.h>
|
#include <mach/db5500-regs.h>
|
||||||
#include "db5500-prcmu-regs.h"
|
#include "dbx500-prcmu-regs.h"
|
||||||
|
|
||||||
#define _PRCM_MB_HEADER (tcdm_base + 0xFE8)
|
#define _PRCM_MB_HEADER (tcdm_base + 0xFE8)
|
||||||
#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0)
|
#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0)
|
||||||
|
@ -109,15 +109,18 @@ enum mb5_header {
|
||||||
#define PRCMU_DSI_CLOCK_SETTING 0x00000128
|
#define PRCMU_DSI_CLOCK_SETTING 0x00000128
|
||||||
/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */
|
/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */
|
||||||
#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135
|
#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135
|
||||||
#define PRCMU_PLLDSI_FREQ_SETTING 0x0004013C
|
#define PRCMU_PLLDSI_FREQ_SETTING 0x00020121
|
||||||
#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002
|
#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002
|
||||||
#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000101
|
#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201
|
||||||
#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101
|
#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101
|
||||||
|
|
||||||
#define PRCMU_ENABLE_PLLDSI 0x00000001
|
#define PRCMU_ENABLE_PLLDSI 0x00000001
|
||||||
#define PRCMU_DISABLE_PLLDSI 0x00000000
|
#define PRCMU_DISABLE_PLLDSI 0x00000000
|
||||||
|
|
||||||
#define PRCMU_DSI_RESET_SW 0x00000003
|
#define PRCMU_DSI_RESET_SW 0x00000003
|
||||||
|
#define PRCMU_RESOUTN0_PIN 0x00000001
|
||||||
|
#define PRCMU_RESOUTN1_PIN 0x00000002
|
||||||
|
#define PRCMU_RESOUTN2_PIN 0x00000004
|
||||||
|
|
||||||
#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3
|
#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3
|
||||||
|
|
||||||
|
@ -315,31 +318,31 @@ static bool read_mailbox_0(void)
|
||||||
r = false;
|
r = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_1(void)
|
static bool read_mailbox_1(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_2(void)
|
static bool read_mailbox_2(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_3(void)
|
static bool read_mailbox_3(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_4(void)
|
static bool read_mailbox_4(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,19 +363,19 @@ static bool read_mailbox_5(void)
|
||||||
print_unknown_header_warning(5, header);
|
print_unknown_header_warning(5, header);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_6(void)
|
static bool read_mailbox_6(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_mailbox_7(void)
|
static bool read_mailbox_7(void)
|
||||||
{
|
{
|
||||||
writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
|
writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +437,7 @@ int __init db5500_prcmu_init(void)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Clean up the mailbox interrupts after pre-kernel code. */
|
/* Clean up the mailbox interrupts after pre-kernel code. */
|
||||||
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR);
|
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
|
||||||
|
|
||||||
r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler,
|
r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler,
|
||||||
prcmu_irq_thread_fn, 0, "prcmu", NULL);
|
prcmu_irq_thread_fn, 0, "prcmu", NULL);
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) STMicroelectronics 2009
|
|
||||||
* Copyright (C) ST-Ericsson SA 2010
|
|
||||||
*
|
|
||||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
|
||||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
|
||||||
*
|
|
||||||
* License Terms: GNU General Public License v2
|
|
||||||
*
|
|
||||||
* PRCM Unit registers
|
|
||||||
*/
|
|
||||||
#ifndef __DB8500_PRCMU_REGS_H
|
|
||||||
#define __DB8500_PRCMU_REGS_H
|
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <mach/hardware.h>
|
|
||||||
|
|
||||||
#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
|
|
||||||
|
|
||||||
#define PRCM_ARM_PLLDIVPS 0x118
|
|
||||||
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE BITS(0, 5)
|
|
||||||
#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xF
|
|
||||||
|
|
||||||
#define PRCM_PLLARM_LOCKP 0x0A8
|
|
||||||
#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1)
|
|
||||||
|
|
||||||
#define PRCM_ARM_CHGCLKREQ 0x114
|
|
||||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0)
|
|
||||||
|
|
||||||
#define PRCM_PLLARM_ENABLE 0x98
|
|
||||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE BIT(0)
|
|
||||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON BIT(8)
|
|
||||||
|
|
||||||
#define PRCM_ARMCLKFIX_MGT 0x0
|
|
||||||
#define PRCM_A9_RESETN_CLR 0x1f4
|
|
||||||
#define PRCM_A9_RESETN_SET 0x1f0
|
|
||||||
#define PRCM_ARM_LS_CLAMP 0x30C
|
|
||||||
#define PRCM_SRAM_A9 0x308
|
|
||||||
|
|
||||||
/* ARM WFI Standby signal register */
|
|
||||||
#define PRCM_ARM_WFI_STANDBY 0x130
|
|
||||||
#define PRCM_IOCR 0x310
|
|
||||||
#define PRCM_IOCR_IOFORCE BIT(0)
|
|
||||||
|
|
||||||
/* CPU mailbox registers */
|
|
||||||
#define PRCM_MBOX_CPU_VAL 0x0FC
|
|
||||||
#define PRCM_MBOX_CPU_SET 0x100
|
|
||||||
|
|
||||||
/* Dual A9 core interrupt management unit registers */
|
|
||||||
#define PRCM_A9_MASK_REQ 0x328
|
|
||||||
#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0)
|
|
||||||
|
|
||||||
#define PRCM_A9_MASK_ACK 0x32C
|
|
||||||
#define PRCM_ARMITMSK31TO0 0x11C
|
|
||||||
#define PRCM_ARMITMSK63TO32 0x120
|
|
||||||
#define PRCM_ARMITMSK95TO64 0x124
|
|
||||||
#define PRCM_ARMITMSK127TO96 0x128
|
|
||||||
#define PRCM_POWER_STATE_VAL 0x25C
|
|
||||||
#define PRCM_ARMITVAL31TO0 0x260
|
|
||||||
#define PRCM_ARMITVAL63TO32 0x264
|
|
||||||
#define PRCM_ARMITVAL95TO64 0x268
|
|
||||||
#define PRCM_ARMITVAL127TO96 0x26C
|
|
||||||
|
|
||||||
#define PRCM_HOSTACCESS_REQ 0x334
|
|
||||||
#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0)
|
|
||||||
|
|
||||||
#define PRCM_ARM_IT1_CLR 0x48C
|
|
||||||
#define PRCM_ARM_IT1_VAL 0x494
|
|
||||||
|
|
||||||
#define PRCM_ITSTATUS0 0x148
|
|
||||||
#define PRCM_ITSTATUS1 0x150
|
|
||||||
#define PRCM_ITSTATUS2 0x158
|
|
||||||
#define PRCM_ITSTATUS3 0x160
|
|
||||||
#define PRCM_ITSTATUS4 0x168
|
|
||||||
#define PRCM_ITSTATUS5 0x484
|
|
||||||
#define PRCM_ITCLEAR5 0x488
|
|
||||||
#define PRCM_ARMIT_MASKXP70_IT 0x1018
|
|
||||||
|
|
||||||
/* System reset register */
|
|
||||||
#define PRCM_APE_SOFTRST 0x228
|
|
||||||
|
|
||||||
/* Level shifter and clamp control registers */
|
|
||||||
#define PRCM_MMIP_LS_CLAMP_SET 0x420
|
|
||||||
#define PRCM_MMIP_LS_CLAMP_CLR 0x424
|
|
||||||
|
|
||||||
/* PRCMU HW semaphore */
|
|
||||||
#define PRCM_SEM 0x400
|
|
||||||
#define PRCM_SEM_PRCM_SEM BIT(0)
|
|
||||||
|
|
||||||
/* PRCMU clock/PLL/reset registers */
|
|
||||||
#define PRCM_PLLDSI_FREQ 0x500
|
|
||||||
#define PRCM_PLLDSI_ENABLE 0x504
|
|
||||||
#define PRCM_PLLDSI_LOCKP 0x508
|
|
||||||
#define PRCM_DSI_PLLOUT_SEL 0x530
|
|
||||||
#define PRCM_DSITVCLK_DIV 0x52C
|
|
||||||
#define PRCM_APE_RESETN_SET 0x1E4
|
|
||||||
#define PRCM_APE_RESETN_CLR 0x1E8
|
|
||||||
|
|
||||||
#define PRCM_TCR 0x1C8
|
|
||||||
#define PRCM_TCR_TENSEL_MASK BITS(0, 7)
|
|
||||||
#define PRCM_TCR_STOP_TIMERS BIT(16)
|
|
||||||
#define PRCM_TCR_DOZE_MODE BIT(17)
|
|
||||||
|
|
||||||
#define PRCM_CLKOCR 0x1CC
|
|
||||||
#define PRCM_CLKOCR_CLKODIV0_SHIFT 0
|
|
||||||
#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5)
|
|
||||||
#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6
|
|
||||||
#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8)
|
|
||||||
#define PRCM_CLKOCR_CLKODIV1_SHIFT 16
|
|
||||||
#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21)
|
|
||||||
#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22
|
|
||||||
#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24)
|
|
||||||
#define PRCM_CLKOCR_CLK1TYPE BIT(28)
|
|
||||||
|
|
||||||
#define PRCM_SGACLK_MGT 0x014
|
|
||||||
#define PRCM_UARTCLK_MGT 0x018
|
|
||||||
#define PRCM_MSP02CLK_MGT 0x01C
|
|
||||||
#define PRCM_MSP1CLK_MGT 0x288
|
|
||||||
#define PRCM_I2CCLK_MGT 0x020
|
|
||||||
#define PRCM_SDMMCCLK_MGT 0x024
|
|
||||||
#define PRCM_SLIMCLK_MGT 0x028
|
|
||||||
#define PRCM_PER1CLK_MGT 0x02C
|
|
||||||
#define PRCM_PER2CLK_MGT 0x030
|
|
||||||
#define PRCM_PER3CLK_MGT 0x034
|
|
||||||
#define PRCM_PER5CLK_MGT 0x038
|
|
||||||
#define PRCM_PER6CLK_MGT 0x03C
|
|
||||||
#define PRCM_PER7CLK_MGT 0x040
|
|
||||||
#define PRCM_LCDCLK_MGT 0x044
|
|
||||||
#define PRCM_BMLCLK_MGT 0x04C
|
|
||||||
#define PRCM_HSITXCLK_MGT 0x050
|
|
||||||
#define PRCM_HSIRXCLK_MGT 0x054
|
|
||||||
#define PRCM_HDMICLK_MGT 0x058
|
|
||||||
#define PRCM_APEATCLK_MGT 0x05C
|
|
||||||
#define PRCM_APETRACECLK_MGT 0x060
|
|
||||||
#define PRCM_MCDECLK_MGT 0x064
|
|
||||||
#define PRCM_IPI2CCLK_MGT 0x068
|
|
||||||
#define PRCM_DSIALTCLK_MGT 0x06C
|
|
||||||
#define PRCM_DMACLK_MGT 0x074
|
|
||||||
#define PRCM_B2R2CLK_MGT 0x078
|
|
||||||
#define PRCM_TVCLK_MGT 0x07C
|
|
||||||
#define PRCM_UNIPROCLK_MGT 0x278
|
|
||||||
#define PRCM_SSPCLK_MGT 0x280
|
|
||||||
#define PRCM_RNGCLK_MGT 0x284
|
|
||||||
#define PRCM_UICCCLK_MGT 0x27C
|
|
||||||
|
|
||||||
#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4)
|
|
||||||
#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7)
|
|
||||||
#define PRCM_CLK_MGT_CLKEN BIT(8)
|
|
||||||
|
|
||||||
/* ePOD and memory power signal control registers */
|
|
||||||
#define PRCM_EPOD_C_SET 0x410
|
|
||||||
#define PRCM_SRAM_LS_SLEEP 0x304
|
|
||||||
|
|
||||||
/* Debug power control unit registers */
|
|
||||||
#define PRCM_POWER_STATE_SET 0x254
|
|
||||||
|
|
||||||
/* Miscellaneous unit registers */
|
|
||||||
#define PRCM_DSI_SW_RESET 0x324
|
|
||||||
#define PRCM_GPIOCR 0x138
|
|
||||||
|
|
||||||
/* GPIOCR register */
|
|
||||||
#define PRCM_GPIOCR_SPI2_SELECT BIT(23)
|
|
||||||
|
|
||||||
#define PRCM_DDR_SUBSYS_APE_MINBW 0x438
|
|
||||||
|
|
||||||
#endif /* __DB8500_PRCMU_REGS_H */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,11 +10,49 @@
|
||||||
* PRCM Unit registers
|
* PRCM Unit registers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MACH_PRCMU_REGS_H
|
#ifndef __DB8500_PRCMU_REGS_H
|
||||||
#define __MACH_PRCMU_REGS_H
|
#define __DB8500_PRCMU_REGS_H
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
|
#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
|
||||||
|
|
||||||
|
#define PRCM_SVACLK_MGT_OFF 0x008
|
||||||
|
#define PRCM_SIACLK_MGT_OFF 0x00C
|
||||||
|
#define PRCM_SGACLK_MGT_OFF 0x014
|
||||||
|
#define PRCM_UARTCLK_MGT_OFF 0x018
|
||||||
|
#define PRCM_MSP02CLK_MGT_OFF 0x01C
|
||||||
|
#define PRCM_I2CCLK_MGT_OFF 0x020
|
||||||
|
#define PRCM_SDMMCCLK_MGT_OFF 0x024
|
||||||
|
#define PRCM_SLIMCLK_MGT_OFF 0x028
|
||||||
|
#define PRCM_PER1CLK_MGT_OFF 0x02C
|
||||||
|
#define PRCM_PER2CLK_MGT_OFF 0x030
|
||||||
|
#define PRCM_PER3CLK_MGT_OFF 0x034
|
||||||
|
#define PRCM_PER5CLK_MGT_OFF 0x038
|
||||||
|
#define PRCM_PER6CLK_MGT_OFF 0x03C
|
||||||
|
#define PRCM_PER7CLK_MGT_OFF 0x040
|
||||||
|
#define PRCM_PWMCLK_MGT_OFF 0x044 /* for DB5500 */
|
||||||
|
#define PRCM_IRDACLK_MGT_OFF 0x048 /* for DB5500 */
|
||||||
|
#define PRCM_IRRCCLK_MGT_OFF 0x04C /* for DB5500 */
|
||||||
|
#define PRCM_LCDCLK_MGT_OFF 0x044
|
||||||
|
#define PRCM_BMLCLK_MGT_OFF 0x04C
|
||||||
|
#define PRCM_HSITXCLK_MGT_OFF 0x050
|
||||||
|
#define PRCM_HSIRXCLK_MGT_OFF 0x054
|
||||||
|
#define PRCM_HDMICLK_MGT_OFF 0x058
|
||||||
|
#define PRCM_APEATCLK_MGT_OFF 0x05C
|
||||||
|
#define PRCM_APETRACECLK_MGT_OFF 0x060
|
||||||
|
#define PRCM_MCDECLK_MGT_OFF 0x064
|
||||||
|
#define PRCM_IPI2CCLK_MGT_OFF 0x068
|
||||||
|
#define PRCM_DSIALTCLK_MGT_OFF 0x06C
|
||||||
|
#define PRCM_DMACLK_MGT_OFF 0x074
|
||||||
|
#define PRCM_B2R2CLK_MGT_OFF 0x078
|
||||||
|
#define PRCM_TVCLK_MGT_OFF 0x07C
|
||||||
|
#define PRCM_UNIPROCLK_MGT_OFF 0x278
|
||||||
|
#define PRCM_SSPCLK_MGT_OFF 0x280
|
||||||
|
#define PRCM_RNGCLK_MGT_OFF 0x284
|
||||||
|
#define PRCM_UICCCLK_MGT_OFF 0x27C
|
||||||
|
#define PRCM_MSP1CLK_MGT_OFF 0x288
|
||||||
|
|
||||||
#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118)
|
#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118)
|
||||||
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f
|
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f
|
||||||
#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf
|
#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf
|
||||||
|
@ -30,11 +68,15 @@
|
||||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100
|
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100
|
||||||
|
|
||||||
#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0)
|
#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0)
|
||||||
|
#define PRCM_A9PL_FORCE_CLKEN (_PRCMU_BASE + 0x19C)
|
||||||
#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4)
|
#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4)
|
||||||
#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0)
|
#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0)
|
||||||
#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c)
|
#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c)
|
||||||
#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308)
|
#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308)
|
||||||
|
|
||||||
|
#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN BIT(0)
|
||||||
|
#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN BIT(1)
|
||||||
|
|
||||||
/* ARM WFI Standby signal register */
|
/* ARM WFI Standby signal register */
|
||||||
#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130)
|
#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130)
|
||||||
#define PRCM_IOCR (_PRCMU_BASE + 0x310)
|
#define PRCM_IOCR (_PRCMU_BASE + 0x310)
|
||||||
|
@ -61,12 +103,18 @@
|
||||||
#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C)
|
#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C)
|
||||||
|
|
||||||
#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334)
|
#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334)
|
||||||
|
#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1
|
||||||
#define ARM_WAKEUP_MODEM 0x1
|
#define ARM_WAKEUP_MODEM 0x1
|
||||||
|
|
||||||
#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C)
|
#define PRCM_ARM_IT1_CLR (_PRCMU_BASE + 0x48C)
|
||||||
#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494)
|
#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494)
|
||||||
#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174)
|
#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174)
|
||||||
|
|
||||||
|
#define PRCM_MOD_AWAKE_STATUS (_PRCMU_BASE + 0x4A0)
|
||||||
|
#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE BIT(0)
|
||||||
|
#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE BIT(1)
|
||||||
|
#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_VMODEM_OFF_ISO BIT(2)
|
||||||
|
|
||||||
#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148)
|
#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148)
|
||||||
#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150)
|
#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150)
|
||||||
#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158)
|
#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158)
|
||||||
|
@ -87,16 +135,21 @@
|
||||||
#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
|
#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
|
||||||
#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
|
#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
|
||||||
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
||||||
#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044)
|
#define PRCM_LCDCLK_MGT (_PRCMU_BASE + PRCM_LCDCLK_MGT_OFF)
|
||||||
#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064)
|
#define PRCM_MCDECLK_MGT (_PRCMU_BASE + PRCM_MCDECLK_MGT_OFF)
|
||||||
#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058)
|
#define PRCM_HDMICLK_MGT (_PRCMU_BASE + PRCM_HDMICLK_MGT_OFF)
|
||||||
#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c)
|
#define PRCM_TVCLK_MGT (_PRCMU_BASE + PRCM_TVCLK_MGT_OFF)
|
||||||
#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
|
#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
|
||||||
#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
|
#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
|
||||||
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
||||||
#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
|
#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
|
||||||
#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
|
#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
|
||||||
|
|
||||||
#define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC)
|
#define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC)
|
||||||
|
#define PRCM_CLKOCR_CLKOUT0_REF_CLK (1 << 0)
|
||||||
|
#define PRCM_CLKOCR_CLKOUT0_MASK BITS(0, 13)
|
||||||
|
#define PRCM_CLKOCR_CLKOUT1_REF_CLK (1 << 16)
|
||||||
|
#define PRCM_CLKOCR_CLKOUT1_MASK BITS(16, 29)
|
||||||
|
|
||||||
/* ePOD and memory power signal control registers */
|
/* ePOD and memory power signal control registers */
|
||||||
#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410)
|
#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410)
|
||||||
|
@ -111,5 +164,41 @@
|
||||||
#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800
|
#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800
|
||||||
#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1
|
#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1
|
||||||
|
|
||||||
|
/* PRCMU HW semaphore */
|
||||||
|
#define PRCM_SEM (_PRCMU_BASE + 0x400)
|
||||||
|
#define PRCM_SEM_PRCM_SEM BIT(0)
|
||||||
|
|
||||||
#endif /* __MACH_PRCMU__REGS_H */
|
#define PRCM_TCR (_PRCMU_BASE + 0x1C8)
|
||||||
|
#define PRCM_TCR_TENSEL_MASK BITS(0, 7)
|
||||||
|
#define PRCM_TCR_STOP_TIMERS BIT(16)
|
||||||
|
#define PRCM_TCR_DOZE_MODE BIT(17)
|
||||||
|
|
||||||
|
#define PRCM_CLKOCR_CLKODIV0_SHIFT 0
|
||||||
|
#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5)
|
||||||
|
#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6
|
||||||
|
#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8)
|
||||||
|
#define PRCM_CLKOCR_CLKODIV1_SHIFT 16
|
||||||
|
#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21)
|
||||||
|
#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22
|
||||||
|
#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24)
|
||||||
|
#define PRCM_CLKOCR_CLK1TYPE BIT(28)
|
||||||
|
|
||||||
|
#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4)
|
||||||
|
#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7)
|
||||||
|
#define PRCM_CLK_MGT_CLKEN BIT(8)
|
||||||
|
|
||||||
|
/* GPIOCR register */
|
||||||
|
#define PRCM_GPIOCR_SPI2_SELECT BIT(23)
|
||||||
|
|
||||||
|
#define PRCM_DDR_SUBSYS_APE_MINBW (_PRCMU_BASE + 0x438)
|
||||||
|
#define PRCM_CGATING_BYPASS (_PRCMU_BASE + 0x134)
|
||||||
|
#define PRCM_CGATING_BYPASS_ICN2 BIT(6)
|
||||||
|
|
||||||
|
/* Miscellaneous unit registers */
|
||||||
|
#define PRCM_RESOUTN_SET (_PRCMU_BASE + 0x214)
|
||||||
|
#define PRCM_RESOUTN_CLR (_PRCMU_BASE + 0x218)
|
||||||
|
|
||||||
|
/* System reset register */
|
||||||
|
#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228)
|
||||||
|
|
||||||
|
#endif /* __DB8500_PRCMU_REGS_H */
|
|
@ -0,0 +1,502 @@
|
||||||
|
/*
|
||||||
|
* Driver for Intel MSIC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011, Intel Corporation
|
||||||
|
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
#include <linux/mfd/intel_msic.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <asm/intel_scu_ipc.h>
|
||||||
|
|
||||||
|
#define MSIC_VENDOR(id) ((id >> 6) & 3)
|
||||||
|
#define MSIC_VERSION(id) (id & 0x3f)
|
||||||
|
#define MSIC_MAJOR(id) ('A' + ((id >> 3) & 7))
|
||||||
|
#define MSIC_MINOR(id) (id & 7)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MSIC interrupt tree is readable from SRAM at INTEL_MSIC_IRQ_PHYS_BASE.
|
||||||
|
* Since IRQ block starts from address 0x002 we need to substract that from
|
||||||
|
* the actual IRQ status register address.
|
||||||
|
*/
|
||||||
|
#define MSIC_IRQ_STATUS(x) (INTEL_MSIC_IRQ_PHYS_BASE + ((x) - 2))
|
||||||
|
#define MSIC_IRQ_STATUS_ACCDET MSIC_IRQ_STATUS(INTEL_MSIC_ACCDET)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SCU hardware has limitation of 16 bytes per read/write buffer on
|
||||||
|
* Medfield.
|
||||||
|
*/
|
||||||
|
#define SCU_IPC_RWBUF_LIMIT 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct intel_msic - an MSIC MFD instance
|
||||||
|
* @pdev: pointer to the platform device
|
||||||
|
* @vendor: vendor ID
|
||||||
|
* @version: chip version
|
||||||
|
* @irq_base: base address of the mapped MSIC SRAM interrupt tree
|
||||||
|
*/
|
||||||
|
struct intel_msic {
|
||||||
|
struct platform_device *pdev;
|
||||||
|
unsigned vendor;
|
||||||
|
unsigned version;
|
||||||
|
void __iomem *irq_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_touch_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_adc_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_battery_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_gpio_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_audio_resources[] = {
|
||||||
|
{
|
||||||
|
.name = "IRQ",
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
* We will pass IRQ_BASE to the driver now but this can be removed
|
||||||
|
* when/if the driver starts to use intel_msic_irq_read().
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.name = "IRQ_BASE",
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
.start = MSIC_IRQ_STATUS_ACCDET,
|
||||||
|
.end = MSIC_IRQ_STATUS_ACCDET,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_hdmi_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_thermal_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_power_btn_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource msic_ocd_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Devices that are part of the MSIC and are available via firmware
|
||||||
|
* populated SFI DEVS table.
|
||||||
|
*/
|
||||||
|
static struct mfd_cell msic_devs[] = {
|
||||||
|
[INTEL_MSIC_BLOCK_TOUCH] = {
|
||||||
|
.name = "msic_touch",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_touch_resources),
|
||||||
|
.resources = msic_touch_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_ADC] = {
|
||||||
|
.name = "msic_adc",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_adc_resources),
|
||||||
|
.resources = msic_adc_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_BATTERY] = {
|
||||||
|
.name = "msic_battery",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_battery_resources),
|
||||||
|
.resources = msic_battery_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_GPIO] = {
|
||||||
|
.name = "msic_gpio",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_gpio_resources),
|
||||||
|
.resources = msic_gpio_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_AUDIO] = {
|
||||||
|
.name = "msic_audio",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_audio_resources),
|
||||||
|
.resources = msic_audio_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_HDMI] = {
|
||||||
|
.name = "msic_hdmi",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_hdmi_resources),
|
||||||
|
.resources = msic_hdmi_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_THERMAL] = {
|
||||||
|
.name = "msic_thermal",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_thermal_resources),
|
||||||
|
.resources = msic_thermal_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_POWER_BTN] = {
|
||||||
|
.name = "msic_power_btn",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_power_btn_resources),
|
||||||
|
.resources = msic_power_btn_resources,
|
||||||
|
},
|
||||||
|
[INTEL_MSIC_BLOCK_OCD] = {
|
||||||
|
.name = "msic_ocd",
|
||||||
|
.num_resources = ARRAY_SIZE(msic_ocd_resources),
|
||||||
|
.resources = msic_ocd_resources,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Other MSIC related devices which are not directly available via SFI DEVS
|
||||||
|
* table. These can be pseudo devices, regulators etc. which are needed for
|
||||||
|
* different purposes.
|
||||||
|
*
|
||||||
|
* These devices appear only after the MSIC driver itself is initialized so
|
||||||
|
* we can guarantee that the SCU IPC interface is ready.
|
||||||
|
*/
|
||||||
|
static struct mfd_cell msic_other_devs[] = {
|
||||||
|
/* Audio codec in the MSIC */
|
||||||
|
{
|
||||||
|
.id = -1,
|
||||||
|
.name = "sn95031",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_reg_read - read a single MSIC register
|
||||||
|
* @reg: register to read
|
||||||
|
* @val: register value is placed here
|
||||||
|
*
|
||||||
|
* Read a single register from MSIC. Returns %0 on success and negative
|
||||||
|
* errno in case of failure.
|
||||||
|
*
|
||||||
|
* Function may sleep.
|
||||||
|
*/
|
||||||
|
int intel_msic_reg_read(unsigned short reg, u8 *val)
|
||||||
|
{
|
||||||
|
return intel_scu_ipc_ioread8(reg, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_reg_read);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_reg_write - write a single MSIC register
|
||||||
|
* @reg: register to write
|
||||||
|
* @val: value to write to that register
|
||||||
|
*
|
||||||
|
* Write a single MSIC register. Returns 0 on success and negative
|
||||||
|
* errno in case of failure.
|
||||||
|
*
|
||||||
|
* Function may sleep.
|
||||||
|
*/
|
||||||
|
int intel_msic_reg_write(unsigned short reg, u8 val)
|
||||||
|
{
|
||||||
|
return intel_scu_ipc_iowrite8(reg, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_reg_write);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_reg_update - update a single MSIC register
|
||||||
|
* @reg: register to update
|
||||||
|
* @val: value to write to the register
|
||||||
|
* @mask: specifies which of the bits are updated (%0 = don't update,
|
||||||
|
* %1 = update)
|
||||||
|
*
|
||||||
|
* Perform an update to a register @reg. @mask is used to specify which
|
||||||
|
* bits are updated. Returns %0 in case of success and negative errno in
|
||||||
|
* case of failure.
|
||||||
|
*
|
||||||
|
* Function may sleep.
|
||||||
|
*/
|
||||||
|
int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask)
|
||||||
|
{
|
||||||
|
return intel_scu_ipc_update_register(reg, val, mask);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_reg_update);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_bulk_read - read an array of registers
|
||||||
|
* @reg: array of register addresses to read
|
||||||
|
* @buf: array where the read values are placed
|
||||||
|
* @count: number of registers to read
|
||||||
|
*
|
||||||
|
* Function reads @count registers from the MSIC using addresses passed in
|
||||||
|
* @reg. Read values are placed in @buf. Reads are performed atomically
|
||||||
|
* wrt. MSIC.
|
||||||
|
*
|
||||||
|
* Returns %0 in case of success and negative errno in case of failure.
|
||||||
|
*
|
||||||
|
* Function may sleep.
|
||||||
|
*/
|
||||||
|
int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count)
|
||||||
|
{
|
||||||
|
if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return intel_scu_ipc_readv(reg, buf, count);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_bulk_read);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_bulk_write - write an array of values to the MSIC registers
|
||||||
|
* @reg: array of registers to write
|
||||||
|
* @buf: values to write to each register
|
||||||
|
* @count: number of registers to write
|
||||||
|
*
|
||||||
|
* Function writes @count registers in @buf to MSIC. Writes are performed
|
||||||
|
* atomically wrt MSIC. Returns %0 in case of success and negative errno in
|
||||||
|
* case of failure.
|
||||||
|
*
|
||||||
|
* Function may sleep.
|
||||||
|
*/
|
||||||
|
int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count)
|
||||||
|
{
|
||||||
|
if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return intel_scu_ipc_writev(reg, buf, count);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_bulk_write);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_msic_irq_read - read a register from an MSIC interrupt tree
|
||||||
|
* @msic: MSIC instance
|
||||||
|
* @reg: interrupt register (between %INTEL_MSIC_IRQLVL1 and
|
||||||
|
* %INTEL_MSIC_RESETIRQ2)
|
||||||
|
* @val: value of the register is placed here
|
||||||
|
*
|
||||||
|
* This function can be used by an MSIC subdevice interrupt handler to read
|
||||||
|
* a register value from the MSIC interrupt tree. In this way subdevice
|
||||||
|
* drivers don't have to map in the interrupt tree themselves but can just
|
||||||
|
* call this function instead.
|
||||||
|
*
|
||||||
|
* Function doesn't sleep and is callable from interrupt context.
|
||||||
|
*
|
||||||
|
* Returns %-EINVAL if @reg is outside of the allowed register region.
|
||||||
|
*/
|
||||||
|
int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val)
|
||||||
|
{
|
||||||
|
if (WARN_ON(reg < INTEL_MSIC_IRQLVL1 || reg > INTEL_MSIC_RESETIRQ2))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*val = readb(msic->irq_base + (reg - INTEL_MSIC_IRQLVL1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(intel_msic_irq_read);
|
||||||
|
|
||||||
|
static int __devinit intel_msic_init_devices(struct intel_msic *msic)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = msic->pdev;
|
||||||
|
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
if (pdata->gpio) {
|
||||||
|
struct mfd_cell *cell = &msic_devs[INTEL_MSIC_BLOCK_GPIO];
|
||||||
|
|
||||||
|
cell->platform_data = pdata->gpio;
|
||||||
|
cell->pdata_size = sizeof(*pdata->gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdata->ocd) {
|
||||||
|
unsigned gpio = pdata->ocd->gpio;
|
||||||
|
|
||||||
|
ret = gpio_request_one(gpio, GPIOF_IN, "ocd_gpio");
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to register OCD GPIO\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gpio_to_irq(gpio);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "no IRQ number for OCD GPIO\n");
|
||||||
|
gpio_free(gpio);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the IRQ number for the OCD */
|
||||||
|
pdata->irq[INTEL_MSIC_BLOCK_OCD] = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(msic_devs); i++) {
|
||||||
|
if (!pdata->irq[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL,
|
||||||
|
pdata->irq[i]);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs,
|
||||||
|
ARRAY_SIZE(msic_other_devs), NULL, 0);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mfd_remove_devices(&pdev->dev);
|
||||||
|
if (pdata->ocd)
|
||||||
|
gpio_free(pdata->ocd->gpio);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __devexit intel_msic_remove_devices(struct intel_msic *msic)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = msic->pdev;
|
||||||
|
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
|
||||||
|
mfd_remove_devices(&pdev->dev);
|
||||||
|
|
||||||
|
if (pdata->ocd)
|
||||||
|
gpio_free(pdata->ocd->gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit intel_msic_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
struct intel_msic *msic;
|
||||||
|
struct resource *res;
|
||||||
|
u8 id0, id1;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(&pdev->dev, "no platform data passed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First validate that we have an MSIC in place */
|
||||||
|
ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID0, &id0);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to identify the MSIC chip (ID0)\n");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID1, &id1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to identify the MSIC chip (ID1)\n");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MSIC_VENDOR(id0) != MSIC_VENDOR(id1)) {
|
||||||
|
dev_err(&pdev->dev, "invalid vendor ID: %x, %x\n", id0, id1);
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
msic = kzalloc(sizeof(*msic), GFP_KERNEL);
|
||||||
|
if (!msic)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
msic->vendor = MSIC_VENDOR(id0);
|
||||||
|
msic->version = MSIC_VERSION(id0);
|
||||||
|
msic->pdev = pdev;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map in the MSIC interrupt tree area in SRAM. This is exposed to
|
||||||
|
* the clients via intel_msic_irq_read().
|
||||||
|
*/
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res) {
|
||||||
|
dev_err(&pdev->dev, "failed to get SRAM iomem resource\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto fail_free_msic;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = request_mem_region(res->start, resource_size(res), pdev->name);
|
||||||
|
if (!res) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto fail_free_msic;
|
||||||
|
}
|
||||||
|
|
||||||
|
msic->irq_base = ioremap_nocache(res->start, resource_size(res));
|
||||||
|
if (!msic->irq_base) {
|
||||||
|
dev_err(&pdev->dev, "failed to map SRAM memory\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto fail_release_region;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, msic);
|
||||||
|
|
||||||
|
ret = intel_msic_init_devices(msic);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to initialize MSIC devices\n");
|
||||||
|
goto fail_unmap_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n",
|
||||||
|
MSIC_MAJOR(msic->version), MSIC_MINOR(msic->version),
|
||||||
|
msic->vendor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail_unmap_mem:
|
||||||
|
iounmap(msic->irq_base);
|
||||||
|
fail_release_region:
|
||||||
|
release_mem_region(res->start, resource_size(res));
|
||||||
|
fail_free_msic:
|
||||||
|
kfree(msic);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit intel_msic_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct intel_msic *msic = platform_get_drvdata(pdev);
|
||||||
|
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
|
||||||
|
intel_msic_remove_devices(msic);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
iounmap(msic->irq_base);
|
||||||
|
release_mem_region(res->start, resource_size(res));
|
||||||
|
kfree(msic);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver intel_msic_driver = {
|
||||||
|
.probe = intel_msic_probe,
|
||||||
|
.remove = __devexit_p(intel_msic_remove),
|
||||||
|
.driver = {
|
||||||
|
.name = "intel_msic",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init intel_msic_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&intel_msic_driver);
|
||||||
|
}
|
||||||
|
module_init(intel_msic_init);
|
||||||
|
|
||||||
|
static void __exit intel_msic_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&intel_msic_driver);
|
||||||
|
}
|
||||||
|
module_exit(intel_msic_exit);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Driver for Intel MSIC");
|
||||||
|
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -328,7 +328,7 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct platform_driver jz4740_adc_driver = {
|
static struct platform_driver jz4740_adc_driver = {
|
||||||
.probe = jz4740_adc_probe,
|
.probe = jz4740_adc_probe,
|
||||||
.remove = __devexit_p(jz4740_adc_remove),
|
.remove = __devexit_p(jz4740_adc_remove),
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
|
@ -142,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
|
||||||
|
|
||||||
max8997->irq_base = pdata->irq_base;
|
max8997->irq_base = pdata->irq_base;
|
||||||
max8997->ono = pdata->ono;
|
max8997->ono = pdata->ono;
|
||||||
max8997->wakeup = pdata->wakeup;
|
|
||||||
|
|
||||||
mutex_init(&max8997->iolock);
|
mutex_init(&max8997->iolock);
|
||||||
|
|
||||||
|
@ -169,6 +169,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_mfd;
|
goto err_mfd;
|
||||||
|
|
||||||
|
/* MAX8997 has a power button input. */
|
||||||
|
device_init_wakeup(max8997->dev, pdata->wakeup);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_mfd:
|
err_mfd:
|
||||||
|
@ -398,7 +401,29 @@ static int max8997_restore(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int max8997_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
|
||||||
|
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
|
||||||
|
|
||||||
|
if (device_may_wakeup(dev))
|
||||||
|
irq_set_irq_wake(max8997->irq, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max8997_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
|
||||||
|
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
|
||||||
|
|
||||||
|
if (device_may_wakeup(dev))
|
||||||
|
irq_set_irq_wake(max8997->irq, 0);
|
||||||
|
return max8997_irq_resume(max8997);
|
||||||
|
}
|
||||||
|
|
||||||
const struct dev_pm_ops max8997_pm = {
|
const struct dev_pm_ops max8997_pm = {
|
||||||
|
.suspend = max8997_suspend,
|
||||||
|
.resume = max8997_resume,
|
||||||
.freeze = max8997_freeze,
|
.freeze = max8997_freeze,
|
||||||
.restore = max8997_restore,
|
.restore = max8997_restore,
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,20 +26,10 @@ struct mc13xxx {
|
||||||
|
|
||||||
irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
|
irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
|
||||||
void *irqdata[MC13XXX_NUM_IRQ];
|
void *irqdata[MC13XXX_NUM_IRQ];
|
||||||
};
|
|
||||||
|
|
||||||
struct mc13783 {
|
|
||||||
struct mc13xxx mc13xxx;
|
|
||||||
|
|
||||||
int adcflags;
|
int adcflags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783)
|
|
||||||
{
|
|
||||||
return &mc13783->mc13xxx;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(mc13783_to_mc13xxx);
|
|
||||||
|
|
||||||
#define MC13XXX_IRQSTAT0 0
|
#define MC13XXX_IRQSTAT0 0
|
||||||
#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
|
#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
|
||||||
#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
|
#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
|
||||||
|
@ -136,14 +126,14 @@ EXPORT_SYMBOL(mc13783_to_mc13xxx);
|
||||||
#define MC13XXX_REVISION_FAB (0x03 << 11)
|
#define MC13XXX_REVISION_FAB (0x03 << 11)
|
||||||
#define MC13XXX_REVISION_ICIDCODE (0x3f << 13)
|
#define MC13XXX_REVISION_ICIDCODE (0x3f << 13)
|
||||||
|
|
||||||
#define MC13783_ADC1 44
|
#define MC13XXX_ADC1 44
|
||||||
#define MC13783_ADC1_ADEN (1 << 0)
|
#define MC13XXX_ADC1_ADEN (1 << 0)
|
||||||
#define MC13783_ADC1_RAND (1 << 1)
|
#define MC13XXX_ADC1_RAND (1 << 1)
|
||||||
#define MC13783_ADC1_ADSEL (1 << 3)
|
#define MC13XXX_ADC1_ADSEL (1 << 3)
|
||||||
#define MC13783_ADC1_ASC (1 << 20)
|
#define MC13XXX_ADC1_ASC (1 << 20)
|
||||||
#define MC13783_ADC1_ADTRIGIGN (1 << 21)
|
#define MC13XXX_ADC1_ADTRIGIGN (1 << 21)
|
||||||
|
|
||||||
#define MC13783_ADC2 45
|
#define MC13XXX_ADC2 45
|
||||||
|
|
||||||
#define MC13XXX_NUMREGS 0x3f
|
#define MC13XXX_NUMREGS 0x3f
|
||||||
|
|
||||||
|
@ -487,7 +477,7 @@ enum mc13xxx_id {
|
||||||
MC13XXX_ID_INVALID,
|
MC13XXX_ID_INVALID,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *mc13xxx_chipname[] = {
|
static const char *mc13xxx_chipname[] = {
|
||||||
[MC13XXX_ID_MC13783] = "mc13783",
|
[MC13XXX_ID_MC13783] = "mc13783",
|
||||||
[MC13XXX_ID_MC13892] = "mc13892",
|
[MC13XXX_ID_MC13892] = "mc13892",
|
||||||
};
|
};
|
||||||
|
@ -558,8 +548,6 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx)
|
||||||
return mc13xxx_chipname[devid->driver_data];
|
return mc13xxx_chipname[devid->driver_data];
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <linux/mfd/mc13783.h>
|
|
||||||
|
|
||||||
int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
|
int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
|
||||||
{
|
{
|
||||||
struct mc13xxx_platform_data *pdata =
|
struct mc13xxx_platform_data *pdata =
|
||||||
|
@ -569,15 +557,15 @@ int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mc13xxx_get_flags);
|
EXPORT_SYMBOL(mc13xxx_get_flags);
|
||||||
|
|
||||||
#define MC13783_ADC1_CHAN0_SHIFT 5
|
#define MC13XXX_ADC1_CHAN0_SHIFT 5
|
||||||
#define MC13783_ADC1_CHAN1_SHIFT 8
|
#define MC13XXX_ADC1_CHAN1_SHIFT 8
|
||||||
|
|
||||||
struct mc13xxx_adcdone_data {
|
struct mc13xxx_adcdone_data {
|
||||||
struct mc13xxx *mc13xxx;
|
struct mc13xxx *mc13xxx;
|
||||||
struct completion done;
|
struct completion done;
|
||||||
};
|
};
|
||||||
|
|
||||||
static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
|
static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct mc13xxx_adcdone_data *adcdone_data = data;
|
struct mc13xxx_adcdone_data *adcdone_data = data;
|
||||||
|
|
||||||
|
@ -588,12 +576,11 @@ static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MC13783_ADC_WORKING (1 << 0)
|
#define MC13XXX_ADC_WORKING (1 << 0)
|
||||||
|
|
||||||
int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
|
int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
|
||||||
unsigned int channel, unsigned int *sample)
|
unsigned int channel, unsigned int *sample)
|
||||||
{
|
{
|
||||||
struct mc13xxx *mc13xxx = &mc13783->mc13xxx;
|
|
||||||
u32 adc0, adc1, old_adc0;
|
u32 adc0, adc1, old_adc0;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
struct mc13xxx_adcdone_data adcdone_data = {
|
struct mc13xxx_adcdone_data adcdone_data = {
|
||||||
|
@ -605,51 +592,51 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
|
||||||
|
|
||||||
mc13xxx_lock(mc13xxx);
|
mc13xxx_lock(mc13xxx);
|
||||||
|
|
||||||
if (mc13783->adcflags & MC13783_ADC_WORKING) {
|
if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc13783->adcflags |= MC13783_ADC_WORKING;
|
mc13xxx->adcflags |= MC13XXX_ADC_WORKING;
|
||||||
|
|
||||||
mc13xxx_reg_read(mc13xxx, MC13783_ADC0, &old_adc0);
|
mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0);
|
||||||
|
|
||||||
adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
|
adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2;
|
||||||
adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
|
adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC;
|
||||||
|
|
||||||
if (channel > 7)
|
if (channel > 7)
|
||||||
adc1 |= MC13783_ADC1_ADSEL;
|
adc1 |= MC13XXX_ADC1_ADSEL;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MC13783_ADC_MODE_TS:
|
case MC13XXX_ADC_MODE_TS:
|
||||||
adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 |
|
adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 |
|
||||||
MC13783_ADC0_TSMOD1;
|
MC13XXX_ADC0_TSMOD1;
|
||||||
adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
|
adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MC13783_ADC_MODE_SINGLE_CHAN:
|
case MC13XXX_ADC_MODE_SINGLE_CHAN:
|
||||||
adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
|
adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
|
||||||
adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
|
adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT;
|
||||||
adc1 |= MC13783_ADC1_RAND;
|
adc1 |= MC13XXX_ADC1_RAND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MC13783_ADC_MODE_MULT_CHAN:
|
case MC13XXX_ADC_MODE_MULT_CHAN:
|
||||||
adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
|
adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
|
||||||
adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
|
adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mc13783_unlock(mc13783);
|
mc13xxx_unlock(mc13xxx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&mc13783->mc13xxx.spidev->dev, "%s: request irq\n", __func__);
|
dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
|
||||||
mc13xxx_irq_request(mc13xxx, MC13783_IRQ_ADCDONE,
|
mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
|
||||||
mc13783_handler_adcdone, __func__, &adcdone_data);
|
mc13xxx_handler_adcdone, __func__, &adcdone_data);
|
||||||
mc13xxx_irq_ack(mc13xxx, MC13783_IRQ_ADCDONE);
|
mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE);
|
||||||
|
|
||||||
mc13xxx_reg_write(mc13xxx, MC13783_ADC0, adc0);
|
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0);
|
||||||
mc13xxx_reg_write(mc13xxx, MC13783_ADC1, adc1);
|
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1);
|
||||||
|
|
||||||
mc13xxx_unlock(mc13xxx);
|
mc13xxx_unlock(mc13xxx);
|
||||||
|
|
||||||
|
@ -660,27 +647,27 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
|
||||||
|
|
||||||
mc13xxx_lock(mc13xxx);
|
mc13xxx_lock(mc13xxx);
|
||||||
|
|
||||||
mc13xxx_irq_free(mc13xxx, MC13783_IRQ_ADCDONE, &adcdone_data);
|
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_ADCDONE, &adcdone_data);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
ret = mc13xxx_reg_read(mc13xxx,
|
ret = mc13xxx_reg_read(mc13xxx,
|
||||||
MC13783_ADC2, &sample[i]);
|
MC13XXX_ADC2, &sample[i]);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MC13783_ADC_MODE_TS)
|
if (mode == MC13XXX_ADC_MODE_TS)
|
||||||
/* restore TSMOD */
|
/* restore TSMOD */
|
||||||
mc13xxx_reg_write(mc13xxx, MC13783_ADC0, old_adc0);
|
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, old_adc0);
|
||||||
|
|
||||||
mc13783->adcflags &= ~MC13783_ADC_WORKING;
|
mc13xxx->adcflags &= ~MC13XXX_ADC_WORKING;
|
||||||
out:
|
out:
|
||||||
mc13xxx_unlock(mc13xxx);
|
mc13xxx_unlock(mc13xxx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
|
EXPORT_SYMBOL_GPL(mc13xxx_adc_do_conversion);
|
||||||
|
|
||||||
static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
|
static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
|
||||||
const char *format, void *pdata, size_t pdata_size)
|
const char *format, void *pdata, size_t pdata_size)
|
||||||
|
@ -716,6 +703,11 @@ static int mc13xxx_probe(struct spi_device *spi)
|
||||||
enum mc13xxx_id id;
|
enum mc13xxx_id id;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(&spi->dev, "invalid platform data\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
|
mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
|
||||||
if (!mc13xxx)
|
if (!mc13xxx)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -763,10 +755,8 @@ err_revision:
|
||||||
if (pdata->flags & MC13XXX_USE_CODEC)
|
if (pdata->flags & MC13XXX_USE_CODEC)
|
||||||
mc13xxx_add_subdevice(mc13xxx, "%s-codec");
|
mc13xxx_add_subdevice(mc13xxx, "%s-codec");
|
||||||
|
|
||||||
if (pdata->flags & MC13XXX_USE_REGULATOR) {
|
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
|
||||||
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
|
&pdata->regulators, sizeof(pdata->regulators));
|
||||||
&pdata->regulators, sizeof(pdata->regulators));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdata->flags & MC13XXX_USE_RTC)
|
if (pdata->flags & MC13XXX_USE_RTC)
|
||||||
mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
|
mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
|
||||||
|
@ -774,10 +764,14 @@ err_revision:
|
||||||
if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
|
if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
|
||||||
mc13xxx_add_subdevice(mc13xxx, "%s-ts");
|
mc13xxx_add_subdevice(mc13xxx, "%s-ts");
|
||||||
|
|
||||||
if (pdata->flags & MC13XXX_USE_LED)
|
if (pdata->leds)
|
||||||
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
|
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
|
||||||
pdata->leds, sizeof(*pdata->leds));
|
pdata->leds, sizeof(*pdata->leds));
|
||||||
|
|
||||||
|
if (pdata->buttons)
|
||||||
|
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
|
||||||
|
pdata->buttons, sizeof(*pdata->buttons));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1226,7 +1226,7 @@ static int menelaus_probe(struct i2c_client *client,
|
||||||
menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
|
menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
|
||||||
|
|
||||||
if (client->irq > 0) {
|
if (client->irq > 0) {
|
||||||
err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED,
|
err = request_irq(client->irq, menelaus_irq, 0,
|
||||||
DRIVER_NAME, menelaus);
|
DRIVER_NAME, menelaus);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
|
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
|
||||||
|
|
|
@ -23,45 +23,22 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <linux/mfd/pcf50633/core.h>
|
#include <linux/mfd/pcf50633/core.h>
|
||||||
|
|
||||||
static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
|
|
||||||
num, data);
|
|
||||||
if (ret < 0)
|
|
||||||
dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
|
|
||||||
num, data);
|
|
||||||
if (ret < 0)
|
|
||||||
dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a block of up to 32 regs */
|
/* Read a block of up to 32 regs */
|
||||||
int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
|
int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
|
||||||
int nr_regs, u8 *data)
|
int nr_regs, u8 *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs);
|
||||||
ret = __pcf50633_read(pcf, reg, nr_regs, data);
|
if (ret != 0)
|
||||||
mutex_unlock(&pcf->lock);
|
return ret;
|
||||||
|
|
||||||
return ret;
|
return nr_regs;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcf50633_read_block);
|
EXPORT_SYMBOL_GPL(pcf50633_read_block);
|
||||||
|
|
||||||
|
@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs);
|
||||||
ret = __pcf50633_write(pcf, reg, nr_regs, data);
|
if (ret != 0)
|
||||||
mutex_unlock(&pcf->lock);
|
return ret;
|
||||||
|
|
||||||
return ret;
|
return nr_regs;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcf50633_write_block);
|
EXPORT_SYMBOL_GPL(pcf50633_write_block);
|
||||||
|
|
||||||
u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
|
u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
|
||||||
{
|
{
|
||||||
u8 val;
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
ret = regmap_read(pcf->regmap, reg, &val);
|
||||||
__pcf50633_read(pcf, reg, 1, &val);
|
if (ret < 0)
|
||||||
mutex_unlock(&pcf->lock);
|
return -1;
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read);
|
||||||
|
|
||||||
int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
|
int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
|
||||||
{
|
{
|
||||||
int ret;
|
return regmap_write(pcf->regmap, reg, val);
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
|
||||||
ret = __pcf50633_write(pcf, reg, 1, &val);
|
|
||||||
mutex_unlock(&pcf->lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcf50633_reg_write);
|
EXPORT_SYMBOL_GPL(pcf50633_reg_write);
|
||||||
|
|
||||||
int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
|
int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
|
||||||
{
|
{
|
||||||
int ret;
|
return regmap_update_bits(pcf->regmap, reg, mask, val);
|
||||||
u8 tmp;
|
|
||||||
|
|
||||||
val &= mask;
|
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
|
||||||
ret = __pcf50633_read(pcf, reg, 1, &tmp);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
tmp &= ~mask;
|
|
||||||
tmp |= val;
|
|
||||||
ret = __pcf50633_write(pcf, reg, 1, &tmp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&pcf->lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
|
EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
|
||||||
|
|
||||||
int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
|
int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
|
||||||
{
|
{
|
||||||
int ret;
|
return regmap_update_bits(pcf->regmap, reg, val, 0);
|
||||||
u8 tmp;
|
|
||||||
|
|
||||||
mutex_lock(&pcf->lock);
|
|
||||||
ret = __pcf50633_read(pcf, reg, 1, &tmp);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
tmp &= ~val;
|
|
||||||
ret = __pcf50633_write(pcf, reg, 1, &tmp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&pcf->lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
|
EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
|
||||||
|
|
||||||
|
@ -251,6 +192,11 @@ static int pcf50633_resume(struct device *dev)
|
||||||
|
|
||||||
static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
|
static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
|
||||||
|
|
||||||
|
static struct regmap_config pcf50633_regmap_config = {
|
||||||
|
.reg_bits = 8,
|
||||||
|
.val_bits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
static int __devinit pcf50633_probe(struct i2c_client *client,
|
static int __devinit pcf50633_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *ids)
|
const struct i2c_device_id *ids)
|
||||||
{
|
{
|
||||||
|
@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
|
||||||
|
|
||||||
mutex_init(&pcf->lock);
|
mutex_init(&pcf->lock);
|
||||||
|
|
||||||
|
pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config);
|
||||||
|
if (IS_ERR(pcf->regmap)) {
|
||||||
|
ret = PTR_ERR(pcf->regmap);
|
||||||
|
dev_err(pcf->dev, "Failed to allocate register map: %d\n",
|
||||||
|
ret);
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(client, pcf);
|
i2c_set_clientdata(client, pcf);
|
||||||
pcf->dev = &client->dev;
|
pcf->dev = &client->dev;
|
||||||
pcf->i2c_client = client;
|
|
||||||
|
|
||||||
version = pcf50633_reg_read(pcf, 0);
|
version = pcf50633_reg_read(pcf, 0);
|
||||||
variant = pcf50633_reg_read(pcf, 1);
|
variant = pcf50633_reg_read(pcf, 1);
|
||||||
if (version < 0 || variant < 0) {
|
if (version < 0 || variant < 0) {
|
||||||
dev_err(pcf->dev, "Unable to probe pcf50633\n");
|
dev_err(pcf->dev, "Unable to probe pcf50633\n");
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto err_free;
|
goto err_regmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(pcf->dev, "Probed device version %d variant %d\n",
|
dev_info(pcf->dev, "Probed device version %d variant %d\n",
|
||||||
|
@ -328,6 +281,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_regmap:
|
||||||
|
regmap_exit(pcf->regmap);
|
||||||
err_free:
|
err_free:
|
||||||
kfree(pcf);
|
kfree(pcf);
|
||||||
|
|
||||||
|
@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
|
||||||
for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
|
for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
|
||||||
platform_device_unregister(pcf->regulator_pdev[i]);
|
platform_device_unregister(pcf->regulator_pdev[i]);
|
||||||
|
|
||||||
|
regmap_exit(pcf->regmap);
|
||||||
kfree(pcf);
|
kfree(pcf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -357,6 +357,7 @@ static int __devexit tc3589x_remove(struct i2c_client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
static int tc3589x_suspend(struct device *dev)
|
static int tc3589x_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct tc3589x *tc3589x = dev_get_drvdata(dev);
|
struct tc3589x *tc3589x = dev_get_drvdata(dev);
|
||||||
|
@ -387,6 +388,7 @@ static int tc3589x_resume(struct device *dev)
|
||||||
|
|
||||||
static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend,
|
static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend,
|
||||||
tc3589x_resume);
|
tc3589x_resume);
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct i2c_device_id tc3589x_id[] = {
|
static const struct i2c_device_id tc3589x_id[] = {
|
||||||
{ "tc3589x", 24 },
|
{ "tc3589x", 24 },
|
||||||
|
|
|
@ -697,7 +697,7 @@ static int __devinit timb_probe(struct pci_dev *dev,
|
||||||
dev_err(&dev->dev, "The driver supports an older "
|
dev_err(&dev->dev, "The driver supports an older "
|
||||||
"version of the FPGA, please update the driver to "
|
"version of the FPGA, please update the driver to "
|
||||||
"support %d.%d\n", priv->fw.major, priv->fw.minor);
|
"support %d.%d\n", priv->fw.major, priv->fw.minor);
|
||||||
goto err_ioremap;
|
goto err_config;
|
||||||
}
|
}
|
||||||
if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
|
if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
|
||||||
priv->fw.minor < TIMB_REQUIRED_MINOR) {
|
priv->fw.minor < TIMB_REQUIRED_MINOR) {
|
||||||
|
@ -705,13 +705,13 @@ static int __devinit timb_probe(struct pci_dev *dev,
|
||||||
"please upgrade the FPGA to at least: %d.%d\n",
|
"please upgrade the FPGA to at least: %d.%d\n",
|
||||||
priv->fw.major, priv->fw.minor,
|
priv->fw.major, priv->fw.minor,
|
||||||
TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
|
TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
|
||||||
goto err_ioremap;
|
goto err_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
|
msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!msix_entries)
|
if (!msix_entries)
|
||||||
goto err_ioremap;
|
goto err_config;
|
||||||
|
|
||||||
for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
|
for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
|
||||||
msix_entries[i].entry = i;
|
msix_entries[i].entry = i;
|
||||||
|
@ -825,6 +825,8 @@ err_mfd:
|
||||||
err_create_file:
|
err_create_file:
|
||||||
pci_disable_msix(dev);
|
pci_disable_msix(dev);
|
||||||
err_msix:
|
err_msix:
|
||||||
|
kfree(msix_entries);
|
||||||
|
err_config:
|
||||||
iounmap(priv->ctl_membase);
|
iounmap(priv->ctl_membase);
|
||||||
err_ioremap:
|
err_ioremap:
|
||||||
release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
|
release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
|
||||||
|
@ -833,7 +835,6 @@ err_request:
|
||||||
err_start:
|
err_start:
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
err_enable:
|
err_enable:
|
||||||
kfree(msix_entries);
|
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
pci_set_drvdata(dev, NULL);
|
pci_set_drvdata(dev, NULL);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
|
@ -131,9 +131,6 @@ int tps65912_device_init(struct tps65912 *tps65912)
|
||||||
if (init_data == NULL)
|
if (init_data == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
init_data->irq = pmic_plat_data->irq;
|
|
||||||
init_data->irq_base = pmic_plat_data->irq;
|
|
||||||
|
|
||||||
mutex_init(&tps65912->io_mutex);
|
mutex_init(&tps65912->io_mutex);
|
||||||
dev_set_drvdata(tps65912->dev, tps65912);
|
dev_set_drvdata(tps65912->dev, tps65912);
|
||||||
|
|
||||||
|
@ -153,10 +150,13 @@ int tps65912_device_init(struct tps65912 *tps65912)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
init_data->irq = pmic_plat_data->irq;
|
||||||
|
init_data->irq_base = pmic_plat_data->irq;
|
||||||
ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
|
ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
kfree(init_data);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
#define twl_has_watchdog() false
|
#define twl_has_watchdog() false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\
|
#if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\
|
||||||
defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE)
|
defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE)
|
||||||
#define twl_has_codec() true
|
#define twl_has_codec() true
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kthread.h>
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <linux/i2c/twl.h>
|
#include <linux/i2c/twl.h>
|
||||||
|
@ -278,59 +277,6 @@ static const struct sih sih_modules_twl5031[8] = {
|
||||||
|
|
||||||
static unsigned twl4030_irq_base;
|
static unsigned twl4030_irq_base;
|
||||||
|
|
||||||
static struct completion irq_event;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This thread processes interrupts reported by the Primary Interrupt Handler.
|
|
||||||
*/
|
|
||||||
static int twl4030_irq_thread(void *data)
|
|
||||||
{
|
|
||||||
long irq = (long)data;
|
|
||||||
static unsigned i2c_errors;
|
|
||||||
static const unsigned max_i2c_errors = 100;
|
|
||||||
|
|
||||||
|
|
||||||
current->flags |= PF_NOFREEZE;
|
|
||||||
|
|
||||||
while (!kthread_should_stop()) {
|
|
||||||
int ret;
|
|
||||||
int module_irq;
|
|
||||||
u8 pih_isr;
|
|
||||||
|
|
||||||
/* Wait for IRQ, then read PIH irq status (also blocking) */
|
|
||||||
wait_for_completion_interruptible(&irq_event);
|
|
||||||
|
|
||||||
ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
|
|
||||||
REG_PIH_ISR_P1);
|
|
||||||
if (ret) {
|
|
||||||
pr_warning("twl4030: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* these handlers deal with the relevant SIH irq status */
|
|
||||||
local_irq_disable();
|
|
||||||
for (module_irq = twl4030_irq_base;
|
|
||||||
pih_isr;
|
|
||||||
pih_isr >>= 1, module_irq++) {
|
|
||||||
if (pih_isr & 0x1)
|
|
||||||
generic_handle_irq(module_irq);
|
|
||||||
}
|
|
||||||
local_irq_enable();
|
|
||||||
|
|
||||||
enable_irq(irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt.
|
* handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt.
|
||||||
* This is a chained interrupt, so there is no desc->action method for it.
|
* This is a chained interrupt, so there is no desc->action method for it.
|
||||||
|
@ -342,9 +288,25 @@ static int twl4030_irq_thread(void *data)
|
||||||
*/
|
*/
|
||||||
static irqreturn_t handle_twl4030_pih(int irq, void *devid)
|
static irqreturn_t handle_twl4030_pih(int irq, void *devid)
|
||||||
{
|
{
|
||||||
/* Acknowledge, clear *AND* mask the interrupt... */
|
int module_irq;
|
||||||
disable_irq_nosync(irq);
|
irqreturn_t ret;
|
||||||
complete(devid);
|
u8 pih_isr;
|
||||||
|
|
||||||
|
ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
|
||||||
|
REG_PIH_ISR_P1);
|
||||||
|
if (ret) {
|
||||||
|
pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret);
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* these handlers deal with the relevant SIH irq status */
|
||||||
|
for (module_irq = twl4030_irq_base;
|
||||||
|
pih_isr;
|
||||||
|
pih_isr >>= 1, module_irq++) {
|
||||||
|
if (pih_isr & 0x1)
|
||||||
|
handle_nested_irq(module_irq);
|
||||||
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
@ -460,114 +422,18 @@ static inline void activate_irq(int irq)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(sih_agent_lock);
|
|
||||||
|
|
||||||
static struct workqueue_struct *wq;
|
|
||||||
|
|
||||||
struct sih_agent {
|
struct sih_agent {
|
||||||
int irq_base;
|
int irq_base;
|
||||||
const struct sih *sih;
|
const struct sih *sih;
|
||||||
|
|
||||||
u32 imr;
|
u32 imr;
|
||||||
bool imr_change_pending;
|
bool imr_change_pending;
|
||||||
struct work_struct mask_work;
|
|
||||||
|
|
||||||
u32 edge_change;
|
u32 edge_change;
|
||||||
struct work_struct edge_work;
|
|
||||||
|
struct mutex irq_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void twl4030_sih_do_mask(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct sih_agent *agent;
|
|
||||||
const struct sih *sih;
|
|
||||||
union {
|
|
||||||
u8 bytes[4];
|
|
||||||
u32 word;
|
|
||||||
} imr;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
agent = container_of(work, struct sih_agent, mask_work);
|
|
||||||
|
|
||||||
/* see what work we have */
|
|
||||||
spin_lock_irq(&sih_agent_lock);
|
|
||||||
if (agent->imr_change_pending) {
|
|
||||||
sih = agent->sih;
|
|
||||||
/* byte[0] gets overwritten as we write ... */
|
|
||||||
imr.word = cpu_to_le32(agent->imr << 8);
|
|
||||||
agent->imr_change_pending = false;
|
|
||||||
} else
|
|
||||||
sih = NULL;
|
|
||||||
spin_unlock_irq(&sih_agent_lock);
|
|
||||||
if (!sih)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* write the whole mask ... simpler than subsetting it */
|
|
||||||
status = twl_i2c_write(sih->module, imr.bytes,
|
|
||||||
sih->mask[irq_line].imr_offset, sih->bytes_ixr);
|
|
||||||
if (status)
|
|
||||||
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
|
||||||
"write", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void twl4030_sih_do_edge(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct sih_agent *agent;
|
|
||||||
const struct sih *sih;
|
|
||||||
u8 bytes[6];
|
|
||||||
u32 edge_change;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
agent = container_of(work, struct sih_agent, edge_work);
|
|
||||||
|
|
||||||
/* see what work we have */
|
|
||||||
spin_lock_irq(&sih_agent_lock);
|
|
||||||
edge_change = agent->edge_change;
|
|
||||||
agent->edge_change = 0;
|
|
||||||
sih = edge_change ? agent->sih : NULL;
|
|
||||||
spin_unlock_irq(&sih_agent_lock);
|
|
||||||
if (!sih)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Read, reserving first byte for write scratch. Yes, this
|
|
||||||
* could be cached for some speedup ... but be careful about
|
|
||||||
* any processor on the other IRQ line, EDR registers are
|
|
||||||
* shared.
|
|
||||||
*/
|
|
||||||
status = twl_i2c_read(sih->module, bytes + 1,
|
|
||||||
sih->edr_offset, sih->bytes_edr);
|
|
||||||
if (status) {
|
|
||||||
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
|
||||||
"read", status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modify only the bits we know must change */
|
|
||||||
while (edge_change) {
|
|
||||||
int i = fls(edge_change) - 1;
|
|
||||||
struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
|
|
||||||
int byte = 1 + (i >> 2);
|
|
||||||
int off = (i & 0x3) * 2;
|
|
||||||
unsigned int type;
|
|
||||||
|
|
||||||
bytes[byte] &= ~(0x03 << off);
|
|
||||||
|
|
||||||
type = irqd_get_trigger_type(idata);
|
|
||||||
if (type & IRQ_TYPE_EDGE_RISING)
|
|
||||||
bytes[byte] |= BIT(off + 1);
|
|
||||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
|
||||||
bytes[byte] |= BIT(off + 0);
|
|
||||||
|
|
||||||
edge_change &= ~BIT(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write */
|
|
||||||
status = twl_i2c_write(sih->module, bytes,
|
|
||||||
sih->edr_offset, sih->bytes_edr);
|
|
||||||
if (status)
|
|
||||||
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
|
||||||
"write", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -579,50 +445,125 @@ static void twl4030_sih_do_edge(struct work_struct *work)
|
||||||
|
|
||||||
static void twl4030_sih_mask(struct irq_data *data)
|
static void twl4030_sih_mask(struct irq_data *data)
|
||||||
{
|
{
|
||||||
struct sih_agent *sih = irq_data_get_irq_chip_data(data);
|
struct sih_agent *agent = irq_data_get_irq_chip_data(data);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&sih_agent_lock, flags);
|
agent->imr |= BIT(data->irq - agent->irq_base);
|
||||||
sih->imr |= BIT(data->irq - sih->irq_base);
|
agent->imr_change_pending = true;
|
||||||
sih->imr_change_pending = true;
|
|
||||||
queue_work(wq, &sih->mask_work);
|
|
||||||
spin_unlock_irqrestore(&sih_agent_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void twl4030_sih_unmask(struct irq_data *data)
|
static void twl4030_sih_unmask(struct irq_data *data)
|
||||||
{
|
{
|
||||||
struct sih_agent *sih = irq_data_get_irq_chip_data(data);
|
struct sih_agent *agent = irq_data_get_irq_chip_data(data);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&sih_agent_lock, flags);
|
agent->imr &= ~BIT(data->irq - agent->irq_base);
|
||||||
sih->imr &= ~BIT(data->irq - sih->irq_base);
|
agent->imr_change_pending = true;
|
||||||
sih->imr_change_pending = true;
|
|
||||||
queue_work(wq, &sih->mask_work);
|
|
||||||
spin_unlock_irqrestore(&sih_agent_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
|
static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
|
||||||
{
|
{
|
||||||
struct sih_agent *sih = irq_data_get_irq_chip_data(data);
|
struct sih_agent *agent = irq_data_get_irq_chip_data(data);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&sih_agent_lock, flags);
|
if (irqd_get_trigger_type(data) != trigger)
|
||||||
if (irqd_get_trigger_type(data) != trigger) {
|
agent->edge_change |= BIT(data->irq - agent->irq_base);
|
||||||
sih->edge_change |= BIT(data->irq - sih->irq_base);
|
|
||||||
queue_work(wq, &sih->edge_work);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&sih_agent_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void twl4030_sih_bus_lock(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct sih_agent *agent = irq_data_get_irq_chip_data(data);
|
||||||
|
|
||||||
|
mutex_lock(&agent->irq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct sih_agent *agent = irq_data_get_irq_chip_data(data);
|
||||||
|
const struct sih *sih = agent->sih;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (agent->imr_change_pending) {
|
||||||
|
union {
|
||||||
|
u32 word;
|
||||||
|
u8 bytes[4];
|
||||||
|
} imr;
|
||||||
|
|
||||||
|
/* byte[0] gets overwriten as we write ... */
|
||||||
|
imr.word = cpu_to_le32(agent->imr << 8);
|
||||||
|
agent->imr_change_pending = false;
|
||||||
|
|
||||||
|
/* write the whole mask ... simpler than subsetting it */
|
||||||
|
status = twl_i2c_write(sih->module, imr.bytes,
|
||||||
|
sih->mask[irq_line].imr_offset,
|
||||||
|
sih->bytes_ixr);
|
||||||
|
if (status)
|
||||||
|
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
||||||
|
"write", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agent->edge_change) {
|
||||||
|
u32 edge_change;
|
||||||
|
u8 bytes[6];
|
||||||
|
|
||||||
|
edge_change = agent->edge_change;
|
||||||
|
agent->edge_change = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read, reserving first byte for write scratch. Yes, this
|
||||||
|
* could be cached for some speedup ... but be careful about
|
||||||
|
* any processor on the other IRQ line, EDR registers are
|
||||||
|
* shared.
|
||||||
|
*/
|
||||||
|
status = twl_i2c_read(sih->module, bytes + 1,
|
||||||
|
sih->edr_offset, sih->bytes_edr);
|
||||||
|
if (status) {
|
||||||
|
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
||||||
|
"read", status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify only the bits we know must change */
|
||||||
|
while (edge_change) {
|
||||||
|
int i = fls(edge_change) - 1;
|
||||||
|
struct irq_data *idata;
|
||||||
|
int byte = 1 + (i >> 2);
|
||||||
|
int off = (i & 0x3) * 2;
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
|
idata = irq_get_irq_data(i + agent->irq_base);
|
||||||
|
|
||||||
|
bytes[byte] &= ~(0x03 << off);
|
||||||
|
|
||||||
|
type = irqd_get_trigger_type(idata);
|
||||||
|
if (type & IRQ_TYPE_EDGE_RISING)
|
||||||
|
bytes[byte] |= BIT(off + 1);
|
||||||
|
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||||
|
bytes[byte] |= BIT(off + 0);
|
||||||
|
|
||||||
|
edge_change &= ~BIT(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write */
|
||||||
|
status = twl_i2c_write(sih->module, bytes,
|
||||||
|
sih->edr_offset, sih->bytes_edr);
|
||||||
|
if (status)
|
||||||
|
pr_err("twl4030: %s, %s --> %d\n", __func__,
|
||||||
|
"write", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&agent->irq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static struct irq_chip twl4030_sih_irq_chip = {
|
static struct irq_chip twl4030_sih_irq_chip = {
|
||||||
.name = "twl4030",
|
.name = "twl4030",
|
||||||
.irq_mask = twl4030_sih_mask,
|
.irq_mask = twl4030_sih_mask,
|
||||||
.irq_unmask = twl4030_sih_unmask,
|
.irq_unmask = twl4030_sih_unmask,
|
||||||
.irq_set_type = twl4030_sih_set_type,
|
.irq_set_type = twl4030_sih_set_type,
|
||||||
|
.irq_bus_lock = twl4030_sih_bus_lock,
|
||||||
|
.irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
@ -655,9 +596,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
|
||||||
int isr;
|
int isr;
|
||||||
|
|
||||||
/* reading ISR acks the IRQs, using clear-on-read mode */
|
/* reading ISR acks the IRQs, using clear-on-read mode */
|
||||||
local_irq_enable();
|
|
||||||
isr = sih_read_isr(sih);
|
isr = sih_read_isr(sih);
|
||||||
local_irq_disable();
|
|
||||||
|
|
||||||
if (isr < 0) {
|
if (isr < 0) {
|
||||||
pr_err("twl4030: %s SIH, read ISR error %d\n",
|
pr_err("twl4030: %s SIH, read ISR error %d\n",
|
||||||
|
@ -672,7 +611,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
|
||||||
isr &= ~BIT(irq);
|
isr &= ~BIT(irq);
|
||||||
|
|
||||||
if (irq < sih->bits)
|
if (irq < sih->bits)
|
||||||
generic_handle_irq(agent->irq_base + irq);
|
handle_nested_irq(agent->irq_base + irq);
|
||||||
else
|
else
|
||||||
pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
|
pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
|
||||||
sih->name, irq);
|
sih->name, irq);
|
||||||
|
@ -718,15 +657,14 @@ int twl4030_sih_setup(int module)
|
||||||
agent->irq_base = irq_base;
|
agent->irq_base = irq_base;
|
||||||
agent->sih = sih;
|
agent->sih = sih;
|
||||||
agent->imr = ~0;
|
agent->imr = ~0;
|
||||||
INIT_WORK(&agent->mask_work, twl4030_sih_do_mask);
|
mutex_init(&agent->irq_lock);
|
||||||
INIT_WORK(&agent->edge_work, twl4030_sih_do_edge);
|
|
||||||
|
|
||||||
for (i = 0; i < sih->bits; i++) {
|
for (i = 0; i < sih->bits; i++) {
|
||||||
irq = irq_base + i;
|
irq = irq_base + i;
|
||||||
|
|
||||||
|
irq_set_chip_data(irq, agent);
|
||||||
irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
|
irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
|
||||||
handle_edge_irq);
|
handle_edge_irq);
|
||||||
irq_set_chip_data(irq, agent);
|
|
||||||
activate_irq(irq);
|
activate_irq(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,7 +696,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
int i;
|
int i;
|
||||||
struct task_struct *task;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mask and clear all TWL4030 interrupts since initially we do
|
* Mask and clear all TWL4030 interrupts since initially we do
|
||||||
|
@ -768,12 +705,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
wq = create_singlethread_workqueue("twl4030-irqchip");
|
|
||||||
if (!wq) {
|
|
||||||
pr_err("twl4030: workqueue FAIL\n");
|
|
||||||
return -ESRCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
twl4030_irq_base = irq_base;
|
twl4030_irq_base = irq_base;
|
||||||
|
|
||||||
/* install an irq handler for each of the SIH modules;
|
/* install an irq handler for each of the SIH modules;
|
||||||
|
@ -787,6 +718,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
for (i = irq_base; i < irq_end; i++) {
|
for (i = irq_base; i < irq_end; i++) {
|
||||||
irq_set_chip_and_handler(i, &twl4030_irq_chip,
|
irq_set_chip_and_handler(i, &twl4030_irq_chip,
|
||||||
handle_simple_irq);
|
handle_simple_irq);
|
||||||
|
irq_set_nested_thread(i, 1);
|
||||||
activate_irq(i);
|
activate_irq(i);
|
||||||
}
|
}
|
||||||
twl4030_irq_next = i;
|
twl4030_irq_next = i;
|
||||||
|
@ -801,34 +733,22 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* install an irq handler to demultiplex the TWL4030 interrupt */
|
/* install an irq handler to demultiplex the TWL4030 interrupt */
|
||||||
|
status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 0,
|
||||||
|
"TWL4030-PIH", NULL);
|
||||||
init_completion(&irq_event);
|
|
||||||
|
|
||||||
status = request_irq(irq_num, handle_twl4030_pih, IRQF_DISABLED,
|
|
||||||
"TWL4030-PIH", &irq_event);
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
|
pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
|
||||||
goto fail_rqirq;
|
goto fail_rqirq;
|
||||||
}
|
}
|
||||||
|
|
||||||
task = kthread_run(twl4030_irq_thread, (void *)(long)irq_num,
|
|
||||||
"twl4030-irq");
|
|
||||||
if (IS_ERR(task)) {
|
|
||||||
pr_err("twl4030: could not create irq %d thread!\n", irq_num);
|
|
||||||
status = PTR_ERR(task);
|
|
||||||
goto fail_kthread;
|
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
fail_kthread:
|
|
||||||
free_irq(irq_num, &irq_event);
|
|
||||||
fail_rqirq:
|
fail_rqirq:
|
||||||
/* clean up twl4030_sih_setup */
|
/* clean up twl4030_sih_setup */
|
||||||
fail:
|
fail:
|
||||||
for (i = irq_base; i < irq_end; i++)
|
for (i = irq_base; i < irq_end; i++) {
|
||||||
|
irq_set_nested_thread(i, 0);
|
||||||
irq_set_chip_and_handler(i, NULL, NULL);
|
irq_set_chip_and_handler(i, NULL, NULL);
|
||||||
destroy_workqueue(wq);
|
}
|
||||||
wq = NULL;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -740,6 +740,28 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev)
|
||||||
TWL4030_BCI_BCICTL1);
|
TWL4030_BCI_BCICTL1);
|
||||||
goto err_i2c;
|
goto err_i2c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that MADC clock is on */
|
||||||
|
ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, ®val, TWL4030_REG_GPBR1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
|
||||||
|
TWL4030_REG_GPBR1);
|
||||||
|
goto err_i2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If MADC clk is not on, turn it on */
|
||||||
|
if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
|
||||||
|
dev_info(&pdev->dev, "clk disabled, enabling\n");
|
||||||
|
regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
|
||||||
|
ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
|
||||||
|
TWL4030_REG_GPBR1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
|
||||||
|
TWL4030_REG_GPBR1);
|
||||||
|
goto err_i2c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, madc);
|
platform_set_drvdata(pdev, madc);
|
||||||
mutex_init(&madc->lock);
|
mutex_init(&madc->lock);
|
||||||
ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
|
ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/i2c/twl.h>
|
#include <linux/i2c/twl.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
|
||||||
#include "twl-core.h"
|
#include "twl-core.h"
|
||||||
|
|
||||||
|
@ -83,8 +84,48 @@ static int twl6030_interrupt_mapping[24] = {
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static unsigned twl6030_irq_base;
|
static unsigned twl6030_irq_base;
|
||||||
|
static int twl_irq;
|
||||||
|
static bool twl_irq_wake_enabled;
|
||||||
|
|
||||||
static struct completion irq_event;
|
static struct completion irq_event;
|
||||||
|
static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0);
|
||||||
|
|
||||||
|
static int twl6030_irq_pm_notifier(struct notifier_block *notifier,
|
||||||
|
unsigned long pm_event, void *unused)
|
||||||
|
{
|
||||||
|
int chained_wakeups;
|
||||||
|
|
||||||
|
switch (pm_event) {
|
||||||
|
case PM_SUSPEND_PREPARE:
|
||||||
|
chained_wakeups = atomic_read(&twl6030_wakeirqs);
|
||||||
|
|
||||||
|
if (chained_wakeups && !twl_irq_wake_enabled) {
|
||||||
|
if (enable_irq_wake(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_irq(twl_irq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PM_POST_SUSPEND:
|
||||||
|
enable_irq(twl_irq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
* This thread processes interrupts reported by the Primary Interrupt Handler.
|
||||||
|
@ -187,6 +228,16 @@ static inline void activate_irq(int irq)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int twl6030_irq_set_wake(struct irq_data *d, unsigned int on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
atomic_inc(&twl6030_wakeirqs);
|
||||||
|
else
|
||||||
|
atomic_dec(&twl6030_wakeirqs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static unsigned twl6030_irq_next;
|
static unsigned twl6030_irq_next;
|
||||||
|
@ -318,10 +369,12 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
twl6030_irq_chip = dummy_irq_chip;
|
twl6030_irq_chip = dummy_irq_chip;
|
||||||
twl6030_irq_chip.name = "twl6030";
|
twl6030_irq_chip.name = "twl6030";
|
||||||
twl6030_irq_chip.irq_set_type = NULL;
|
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++) {
|
for (i = irq_base; i < irq_end; i++) {
|
||||||
irq_set_chip_and_handler(i, &twl6030_irq_chip,
|
irq_set_chip_and_handler(i, &twl6030_irq_chip,
|
||||||
handle_simple_irq);
|
handle_simple_irq);
|
||||||
|
irq_set_chip_data(i, (void *)irq_num);
|
||||||
activate_irq(i);
|
activate_irq(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +384,14 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
|
|
||||||
/* install an irq handler to demultiplex the TWL6030 interrupt */
|
/* install an irq handler to demultiplex the TWL6030 interrupt */
|
||||||
init_completion(&irq_event);
|
init_completion(&irq_event);
|
||||||
|
|
||||||
|
status = request_irq(irq_num, handle_twl6030_pih, 0,
|
||||||
|
"TWL6030-PIH", &irq_event);
|
||||||
|
if (status < 0) {
|
||||||
|
pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
|
||||||
|
goto fail_irq;
|
||||||
|
}
|
||||||
|
|
||||||
task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
|
task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
|
||||||
if (IS_ERR(task)) {
|
if (IS_ERR(task)) {
|
||||||
pr_err("twl6030: could not create irq %d thread!\n", irq_num);
|
pr_err("twl6030: could not create irq %d thread!\n", irq_num);
|
||||||
|
@ -338,17 +399,14 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
||||||
goto fail_kthread;
|
goto fail_kthread;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED,
|
twl_irq = irq_num;
|
||||||
"TWL6030-PIH", &irq_event);
|
register_pm_notifier(&twl6030_irq_pm_notifier_block);
|
||||||
if (status < 0) {
|
|
||||||
pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
|
|
||||||
goto fail_irq;
|
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
fail_irq:
|
|
||||||
free_irq(irq_num, &irq_event);
|
|
||||||
|
|
||||||
fail_kthread:
|
fail_kthread:
|
||||||
|
free_irq(irq_num, &irq_event);
|
||||||
|
|
||||||
|
fail_irq:
|
||||||
for (i = irq_base; i < irq_end; i++)
|
for (i = irq_base; i < irq_end; i++)
|
||||||
irq_set_chip_and_handler(i, NULL, NULL);
|
irq_set_chip_and_handler(i, NULL, NULL);
|
||||||
return status;
|
return status;
|
||||||
|
@ -356,6 +414,7 @@ fail_kthread:
|
||||||
|
|
||||||
int twl6030_exit_irq(void)
|
int twl6030_exit_irq(void)
|
||||||
{
|
{
|
||||||
|
unregister_pm_notifier(&twl6030_irq_pm_notifier_block);
|
||||||
|
|
||||||
if (twl6030_irq_base) {
|
if (twl6030_irq_base) {
|
||||||
pr_err("twl6030: can't yet clean up IRQs?\n");
|
pr_err("twl6030: can't yet clean up IRQs?\n");
|
||||||
|
|
|
@ -420,12 +420,19 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IRQ_TYPE_EDGE_BOTH:
|
case IRQ_TYPE_EDGE_BOTH:
|
||||||
wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;
|
wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;
|
||||||
|
wm831x->gpio_level[irq] = false;
|
||||||
break;
|
break;
|
||||||
case IRQ_TYPE_EDGE_RISING:
|
case IRQ_TYPE_EDGE_RISING:
|
||||||
wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
|
wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
|
||||||
|
wm831x->gpio_level[irq] = false;
|
||||||
break;
|
break;
|
||||||
case IRQ_TYPE_EDGE_FALLING:
|
case IRQ_TYPE_EDGE_FALLING:
|
||||||
wm831x->gpio_update[irq] = 0x10000;
|
wm831x->gpio_update[irq] = 0x10000;
|
||||||
|
wm831x->gpio_level[irq] = false;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_LEVEL_HIGH:
|
||||||
|
wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
|
||||||
|
wm831x->gpio_level[irq] = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -449,7 +456,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct wm831x *wm831x = data;
|
struct wm831x *wm831x = data;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int primary, status_addr;
|
int primary, status_addr, ret;
|
||||||
int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
|
int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
|
||||||
int read[WM831X_NUM_IRQ_REGS] = { 0 };
|
int read[WM831X_NUM_IRQ_REGS] = { 0 };
|
||||||
int *status;
|
int *status;
|
||||||
|
@ -507,6 +514,19 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
|
||||||
|
|
||||||
if (*status & wm831x_irqs[i].mask)
|
if (*status & wm831x_irqs[i].mask)
|
||||||
handle_nested_irq(wm831x->irq_base + i);
|
handle_nested_irq(wm831x->irq_base + i);
|
||||||
|
|
||||||
|
/* Simulate an edge triggered IRQ by polling the input
|
||||||
|
* status. This is sucky but improves interoperability.
|
||||||
|
*/
|
||||||
|
if (primary == WM831X_GP_INT &&
|
||||||
|
wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) {
|
||||||
|
ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
|
||||||
|
while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {
|
||||||
|
handle_nested_irq(wm831x->irq_base + i);
|
||||||
|
ret = wm831x_reg_read(wm831x,
|
||||||
|
WM831X_GPIO_LEVEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -596,8 +616,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
|
||||||
"No interrupt specified - functionality limited\n");
|
"No interrupt specified - functionality limited\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Enable top level interrupts, we mask at secondary level */
|
/* Enable top level interrupts, we mask at secondary level */
|
||||||
wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
|
wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,47 @@ static int wm8994_suspend(struct device *dev)
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (wm8994->type) {
|
||||||
|
case WM8958:
|
||||||
|
ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Failed to read power status: %d\n", ret);
|
||||||
|
} else if (ret & WM8958_MICD_ENA) {
|
||||||
|
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)
|
||||||
|
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
|
||||||
|
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
|
||||||
|
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
|
||||||
|
|
||||||
/* GPIO configuration state is saved here since we may be configuring
|
/* GPIO configuration state is saved here since we may be configuring
|
||||||
* the GPIO alternate functions even if we're not using the gpiolib
|
* the GPIO alternate functions even if we're not using the gpiolib
|
||||||
* driver for them.
|
* driver for them.
|
||||||
|
@ -286,6 +327,11 @@ static int wm8994_resume(struct device *dev)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
|
dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
|
||||||
|
|
||||||
|
/* Disable LDO pulldowns while the device is active */
|
||||||
|
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
|
||||||
|
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
|
||||||
|
0);
|
||||||
|
|
||||||
wm8994->suspended = false;
|
wm8994->suspended = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -467,8 +513,15 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
||||||
pdata->gpio_defaults[i]);
|
pdata->gpio_defaults[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable LDO pulldowns while the device is active */
|
||||||
|
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
|
||||||
|
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
|
||||||
|
0);
|
||||||
|
|
||||||
/* In some system designs where the regulators are not in use,
|
/* In some system designs where the regulators are not in use,
|
||||||
* we can achieve a small reduction in leakage currents by
|
* we can achieve a small reduction in leakage currents by
|
||||||
* floating LDO outputs. This bit makes no difference if the
|
* floating LDO outputs. This bit makes no difference if the
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mfd/db8500-prcmu.h>
|
#include <linux/mfd/dbx500-prcmu.h>
|
||||||
#include <linux/regulator/driver.h>
|
#include <linux/regulator/driver.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/regulator/db8500-prcmu.h>
|
#include <linux/regulator/db8500-prcmu.h>
|
||||||
|
|
|
@ -336,9 +336,9 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13xxx_regulator_priv *priv;
|
struct mc13xxx_regulator_priv *priv;
|
||||||
struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
|
struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
|
||||||
struct mc13783_regulator_platform_data *pdata =
|
struct mc13xxx_regulator_platform_data *pdata =
|
||||||
dev_get_platdata(&pdev->dev);
|
dev_get_platdata(&pdev->dev);
|
||||||
struct mc13783_regulator_init_data *init_data;
|
struct mc13xxx_regulator_init_data *init_data;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
|
dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
|
||||||
|
@ -381,7 +381,7 @@ err:
|
||||||
static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
|
static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
|
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
|
||||||
struct mc13783_regulator_platform_data *pdata =
|
struct mc13xxx_regulator_platform_data *pdata =
|
||||||
dev_get_platdata(&pdev->dev);
|
dev_get_platdata(&pdev->dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,10 @@ enum sample_type {
|
||||||
#define REG_BCICTL2 0x024
|
#define REG_BCICTL2 0x024
|
||||||
#define TWL4030_BCI_ITHSENS 0x007
|
#define TWL4030_BCI_ITHSENS 0x007
|
||||||
|
|
||||||
|
/* Register and bits for GPBR1 register */
|
||||||
|
#define TWL4030_REG_GPBR1 0x0c
|
||||||
|
#define TWL4030_GPBR1_MADC_HFCLK_EN (1 << 7)
|
||||||
|
|
||||||
struct twl4030_madc_user_parms {
|
struct twl4030_madc_user_parms {
|
||||||
int channel;
|
int channel;
|
||||||
int average;
|
int average;
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) ST-Ericsson 2011
|
||||||
|
*
|
||||||
|
* License Terms: GNU General Public License v2
|
||||||
|
*/
|
||||||
|
#ifndef MFD_AB5500_H
|
||||||
|
#define MFD_AB5500_H
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
|
||||||
|
enum ab5500_devid {
|
||||||
|
AB5500_DEVID_ADC,
|
||||||
|
AB5500_DEVID_LEDS,
|
||||||
|
AB5500_DEVID_POWER,
|
||||||
|
AB5500_DEVID_REGULATORS,
|
||||||
|
AB5500_DEVID_SIM,
|
||||||
|
AB5500_DEVID_RTC,
|
||||||
|
AB5500_DEVID_CHARGER,
|
||||||
|
AB5500_DEVID_FUELGAUGE,
|
||||||
|
AB5500_DEVID_VIBRATOR,
|
||||||
|
AB5500_DEVID_CODEC,
|
||||||
|
AB5500_DEVID_USB,
|
||||||
|
AB5500_DEVID_OTP,
|
||||||
|
AB5500_DEVID_VIDEO,
|
||||||
|
AB5500_DEVID_DBIECI,
|
||||||
|
AB5500_DEVID_ONSWA,
|
||||||
|
AB5500_NUM_DEVICES,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ab5500_banks {
|
||||||
|
AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP = 0,
|
||||||
|
AB5500_BANK_VDDDIG_IO_I2C_CLK_TST = 1,
|
||||||
|
AB5500_BANK_VDENC = 2,
|
||||||
|
AB5500_BANK_SIM_USBSIM = 3,
|
||||||
|
AB5500_BANK_LED = 4,
|
||||||
|
AB5500_BANK_ADC = 5,
|
||||||
|
AB5500_BANK_RTC = 6,
|
||||||
|
AB5500_BANK_STARTUP = 7,
|
||||||
|
AB5500_BANK_DBI_ECI = 8,
|
||||||
|
AB5500_BANK_CHG = 9,
|
||||||
|
AB5500_BANK_FG_BATTCOM_ACC = 10,
|
||||||
|
AB5500_BANK_USB = 11,
|
||||||
|
AB5500_BANK_IT = 12,
|
||||||
|
AB5500_BANK_VIBRA = 13,
|
||||||
|
AB5500_BANK_AUDIO_HEADSETUSB = 14,
|
||||||
|
AB5500_NUM_BANKS = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ab5500_banks_addr {
|
||||||
|
AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP = 0x4A,
|
||||||
|
AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST = 0x4B,
|
||||||
|
AB5500_ADDR_VDENC = 0x06,
|
||||||
|
AB5500_ADDR_SIM_USBSIM = 0x04,
|
||||||
|
AB5500_ADDR_LED = 0x10,
|
||||||
|
AB5500_ADDR_ADC = 0x0A,
|
||||||
|
AB5500_ADDR_RTC = 0x0F,
|
||||||
|
AB5500_ADDR_STARTUP = 0x03,
|
||||||
|
AB5500_ADDR_DBI_ECI = 0x07,
|
||||||
|
AB5500_ADDR_CHG = 0x0B,
|
||||||
|
AB5500_ADDR_FG_BATTCOM_ACC = 0x0C,
|
||||||
|
AB5500_ADDR_USB = 0x05,
|
||||||
|
AB5500_ADDR_IT = 0x0E,
|
||||||
|
AB5500_ADDR_VIBRA = 0x02,
|
||||||
|
AB5500_ADDR_AUDIO_HEADSETUSB = 0x0D,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt register offsets
|
||||||
|
* Bank : 0x0E
|
||||||
|
*/
|
||||||
|
#define AB5500_IT_SOURCE0_REG 0x20
|
||||||
|
#define AB5500_IT_SOURCE1_REG 0x21
|
||||||
|
#define AB5500_IT_SOURCE2_REG 0x22
|
||||||
|
#define AB5500_IT_SOURCE3_REG 0x23
|
||||||
|
#define AB5500_IT_SOURCE4_REG 0x24
|
||||||
|
#define AB5500_IT_SOURCE5_REG 0x25
|
||||||
|
#define AB5500_IT_SOURCE6_REG 0x26
|
||||||
|
#define AB5500_IT_SOURCE7_REG 0x27
|
||||||
|
#define AB5500_IT_SOURCE8_REG 0x28
|
||||||
|
#define AB5500_IT_SOURCE9_REG 0x29
|
||||||
|
#define AB5500_IT_SOURCE10_REG 0x2A
|
||||||
|
#define AB5500_IT_SOURCE11_REG 0x2B
|
||||||
|
#define AB5500_IT_SOURCE12_REG 0x2C
|
||||||
|
#define AB5500_IT_SOURCE13_REG 0x2D
|
||||||
|
#define AB5500_IT_SOURCE14_REG 0x2E
|
||||||
|
#define AB5500_IT_SOURCE15_REG 0x2F
|
||||||
|
#define AB5500_IT_SOURCE16_REG 0x30
|
||||||
|
#define AB5500_IT_SOURCE17_REG 0x31
|
||||||
|
#define AB5500_IT_SOURCE18_REG 0x32
|
||||||
|
#define AB5500_IT_SOURCE19_REG 0x33
|
||||||
|
#define AB5500_IT_SOURCE20_REG 0x34
|
||||||
|
#define AB5500_IT_SOURCE21_REG 0x35
|
||||||
|
#define AB5500_IT_SOURCE22_REG 0x36
|
||||||
|
#define AB5500_IT_SOURCE23_REG 0x37
|
||||||
|
|
||||||
|
#define AB5500_NUM_IRQ_REGS 23
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ab5500
|
||||||
|
* @access_mutex: lock out concurrent accesses to the AB registers
|
||||||
|
* @dev: a pointer to the device struct for this chip driver
|
||||||
|
* @ab5500_irq: the analog baseband irq
|
||||||
|
* @irq_base: the platform configuration irq base for subdevices
|
||||||
|
* @chip_name: name of this chip variant
|
||||||
|
* @chip_id: 8 bit chip ID for this chip variant
|
||||||
|
* @irq_lock: a lock to protect the mask
|
||||||
|
* @abb_events: a local bit mask of the prcmu wakeup events
|
||||||
|
* @event_mask: a local copy of the mask event registers
|
||||||
|
* @last_event_mask: a copy of the last event_mask written to hardware
|
||||||
|
* @startup_events: a copy of the first reading of the event registers
|
||||||
|
* @startup_events_read: whether the first events have been read
|
||||||
|
*/
|
||||||
|
struct ab5500 {
|
||||||
|
struct mutex access_mutex;
|
||||||
|
struct device *dev;
|
||||||
|
unsigned int ab5500_irq;
|
||||||
|
unsigned int irq_base;
|
||||||
|
char chip_name[32];
|
||||||
|
u8 chip_id;
|
||||||
|
struct mutex irq_lock;
|
||||||
|
u32 abb_events;
|
||||||
|
u8 mask[AB5500_NUM_IRQ_REGS];
|
||||||
|
u8 oldmask[AB5500_NUM_IRQ_REGS];
|
||||||
|
u8 startup_events[AB5500_NUM_IRQ_REGS];
|
||||||
|
bool startup_events_read;
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
unsigned int debug_bank;
|
||||||
|
unsigned int debug_address;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ab5500_platform_data {
|
||||||
|
struct {unsigned int base; unsigned int count; } irq;
|
||||||
|
void *dev_data[AB5500_NUM_DEVICES];
|
||||||
|
struct abx500_init_settings *init_settings;
|
||||||
|
unsigned int init_settings_sz;
|
||||||
|
bool pm_power_off;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MFD_AB5500_H */
|
|
@ -27,6 +27,9 @@
|
||||||
struct ab8500_gpadc;
|
struct ab8500_gpadc;
|
||||||
|
|
||||||
struct ab8500_gpadc *ab8500_gpadc_get(char *name);
|
struct ab8500_gpadc *ab8500_gpadc_get(char *name);
|
||||||
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input);
|
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel);
|
||||||
|
int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel);
|
||||||
|
int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc,
|
||||||
|
u8 channel, int ad_value);
|
||||||
|
|
||||||
#endif /* _AB8500_GPADC_H */
|
#endif /* _AB8500_GPADC_H */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*
|
*
|
||||||
* ABX500 core access functions.
|
* ABX500 core access functions.
|
||||||
* The abx500 interface is used for the Analog Baseband chip
|
* The abx500 interface is used for the Analog Baseband chip
|
||||||
* ab3100, ab3550, ab5500, and ab8500.
|
* ab3100, ab5500, and ab8500.
|
||||||
*
|
*
|
||||||
* Author: Mattias Wallin <mattias.wallin@stericsson.com>
|
* Author: Mattias Wallin <mattias.wallin@stericsson.com>
|
||||||
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
|
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
|
||||||
|
@ -29,17 +29,16 @@
|
||||||
#define AB3100_P1G 0xc6
|
#define AB3100_P1G 0xc6
|
||||||
#define AB3100_R2A 0xc7
|
#define AB3100_R2A 0xc7
|
||||||
#define AB3100_R2B 0xc8
|
#define AB3100_R2B 0xc8
|
||||||
#define AB3550_P1A 0x10
|
|
||||||
#define AB5500_1_0 0x20
|
#define AB5500_1_0 0x20
|
||||||
#define AB5500_2_0 0x21
|
#define AB5500_1_1 0x21
|
||||||
#define AB5500_2_1 0x22
|
#define AB5500_2_0 0x24
|
||||||
|
|
||||||
/* AB8500 CIDs*/
|
/* AB8500 CIDs*/
|
||||||
#define AB8500_CUTEARLY 0x00
|
|
||||||
#define AB8500_CUT1P0 0x10
|
#define AB8500_CUT1P0 0x10
|
||||||
#define AB8500_CUT1P1 0x11
|
#define AB8500_CUT1P1 0x11
|
||||||
#define AB8500_CUT2P0 0x20
|
#define AB8500_CUT2P0 0x20
|
||||||
#define AB8500_CUT3P0 0x30
|
#define AB8500_CUT3P0 0x30
|
||||||
|
#define AB8500_CUT3P3 0x33
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AB3100, EVENTA1, A2 and A3 event register flags
|
* AB3100, EVENTA1, A2 and A3 event register flags
|
||||||
|
@ -143,39 +142,6 @@ int ab3100_event_register(struct ab3100 *ab3100,
|
||||||
int ab3100_event_unregister(struct ab3100 *ab3100,
|
int ab3100_event_unregister(struct ab3100 *ab3100,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
|
|
||||||
/* AB3550, STR register flags */
|
|
||||||
#define AB3550_STR_ONSWA (0x01)
|
|
||||||
#define AB3550_STR_ONSWB (0x02)
|
|
||||||
#define AB3550_STR_ONSWC (0x04)
|
|
||||||
#define AB3550_STR_DCIO (0x08)
|
|
||||||
#define AB3550_STR_BOOT_MODE (0x10)
|
|
||||||
#define AB3550_STR_SIM_OFF (0x20)
|
|
||||||
#define AB3550_STR_BATT_REMOVAL (0x40)
|
|
||||||
#define AB3550_STR_VBUS (0x80)
|
|
||||||
|
|
||||||
/* Interrupt mask registers */
|
|
||||||
#define AB3550_IMR1 0x29
|
|
||||||
#define AB3550_IMR2 0x2a
|
|
||||||
#define AB3550_IMR3 0x2b
|
|
||||||
#define AB3550_IMR4 0x2c
|
|
||||||
#define AB3550_IMR5 0x2d
|
|
||||||
|
|
||||||
enum ab3550_devid {
|
|
||||||
AB3550_DEVID_ADC,
|
|
||||||
AB3550_DEVID_DAC,
|
|
||||||
AB3550_DEVID_LEDS,
|
|
||||||
AB3550_DEVID_POWER,
|
|
||||||
AB3550_DEVID_REGULATORS,
|
|
||||||
AB3550_DEVID_SIM,
|
|
||||||
AB3550_DEVID_UART,
|
|
||||||
AB3550_DEVID_RTC,
|
|
||||||
AB3550_DEVID_CHARGER,
|
|
||||||
AB3550_DEVID_FUELGAUGE,
|
|
||||||
AB3550_DEVID_VIBRATOR,
|
|
||||||
AB3550_DEVID_CODEC,
|
|
||||||
AB3550_NUM_DEVICES,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct abx500_init_setting
|
* struct abx500_init_setting
|
||||||
* Initial value of the registers for driver to use during setup.
|
* Initial value of the registers for driver to use during setup.
|
||||||
|
@ -186,18 +152,6 @@ struct abx500_init_settings {
|
||||||
u8 setting;
|
u8 setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct ab3550_platform_data
|
|
||||||
* Data supplied to initialize board connections to the AB3550
|
|
||||||
*/
|
|
||||||
struct ab3550_platform_data {
|
|
||||||
struct {unsigned int base; unsigned int count; } irq;
|
|
||||||
void *dev_data[AB3550_NUM_DEVICES];
|
|
||||||
size_t dev_data_sz[AB3550_NUM_DEVICES];
|
|
||||||
struct abx500_init_settings *init_settings;
|
|
||||||
unsigned int init_settings_sz;
|
|
||||||
};
|
|
||||||
|
|
||||||
int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
||||||
u8 value);
|
u8 value);
|
||||||
int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
||||||
|
|
|
@ -5,21 +5,35 @@
|
||||||
*
|
*
|
||||||
* U5500 PRCMU API.
|
* U5500 PRCMU API.
|
||||||
*/
|
*/
|
||||||
#ifndef __MACH_PRCMU_U5500_H
|
#ifndef __MFD_DB5500_PRCMU_H
|
||||||
#define __MACH_PRCMU_U5500_H
|
#define __MFD_DB5500_PRCMU_H
|
||||||
|
|
||||||
#ifdef CONFIG_UX500_SOC_DB5500
|
#ifdef CONFIG_MFD_DB5500_PRCMU
|
||||||
|
|
||||||
void db5500_prcmu_early_init(void);
|
void db5500_prcmu_early_init(void);
|
||||||
|
int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state);
|
||||||
|
int db5500_prcmu_set_display_clocks(void);
|
||||||
|
int db5500_prcmu_disable_dsipll(void);
|
||||||
|
int db5500_prcmu_enable_dsipll(void);
|
||||||
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
||||||
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||||
|
void db5500_prcmu_enable_wakeups(u32 wakeups);
|
||||||
|
int db5500_prcmu_request_clock(u8 clock, bool enable);
|
||||||
|
void db5500_prcmu_config_abb_event_readout(u32 abb_events);
|
||||||
|
void db5500_prcmu_get_abb_event_buffer(void __iomem **buf);
|
||||||
|
int prcmu_resetout(u8 resoutn, u8 state);
|
||||||
|
int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
bool keep_ap_pll);
|
||||||
|
int db5500_prcmu_config_esram0_deep_sleep(u8 state);
|
||||||
|
void db5500_prcmu_system_reset(u16 reset_code);
|
||||||
|
u16 db5500_prcmu_get_reset_code(void);
|
||||||
|
bool db5500_prcmu_is_ac_wake_requested(void);
|
||||||
|
int db5500_prcmu_set_arm_opp(u8 opp);
|
||||||
|
int db5500_prcmu_get_arm_opp(void);
|
||||||
|
|
||||||
#else /* !CONFIG_UX500_SOC_DB5500 */
|
#else /* !CONFIG_UX500_SOC_DB5500 */
|
||||||
|
|
||||||
static inline void db5500_prcmu_early_init(void)
|
static inline void db5500_prcmu_early_init(void) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||||
{
|
{
|
||||||
|
@ -31,15 +45,75 @@ static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_UX500_SOC_DB5500 */
|
static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
|
||||||
|
|
||||||
static inline int db5500_prcmu_config_abb_event_readout(u32 abb_events)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MACH_U5500_SIMULATOR
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __MACH_PRCMU_U5500_H */
|
static inline int db5500_prcmu_set_display_clocks(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_disable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_enable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
|
||||||
|
|
||||||
|
static inline int prcmu_resetout(u8 resoutn, u8 state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
|
||||||
|
static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
bool keep_ap_pll)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void db5500_prcmu_system_reset(u16 reset_code) {}
|
||||||
|
|
||||||
|
static inline u16 db5500_prcmu_get_reset_code(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool db5500_prcmu_is_ac_wake_requested(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_set_arm_opp(u8 opp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db5500_prcmu_get_arm_opp(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CONFIG_MFD_DB5500_PRCMU */
|
||||||
|
|
||||||
|
#endif /* __MFD_DB5500_PRCMU_H */
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define __MFD_DB8500_PRCMU_H
|
#define __MFD_DB8500_PRCMU_H
|
||||||
|
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/notifier.h>
|
|
||||||
|
|
||||||
/* This portion previously known as <mach/prcmu-fw-defs_v1.h> */
|
/* This portion previously known as <mach/prcmu-fw-defs_v1.h> */
|
||||||
|
|
||||||
|
@ -133,7 +132,7 @@ enum ap_pwrst {
|
||||||
* @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle
|
* @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle
|
||||||
*/
|
*/
|
||||||
enum ap_pwrst_trans {
|
enum ap_pwrst_trans {
|
||||||
NO_TRANSITION = 0x00,
|
PRCMU_AP_NO_CHANGE = 0x00,
|
||||||
APEXECUTE_TO_APSLEEP = 0x01,
|
APEXECUTE_TO_APSLEEP = 0x01,
|
||||||
APIDLE_TO_APSLEEP = 0x02, /* To be removed */
|
APIDLE_TO_APSLEEP = 0x02, /* To be removed */
|
||||||
PRCMU_AP_SLEEP = 0x01,
|
PRCMU_AP_SLEEP = 0x01,
|
||||||
|
@ -145,54 +144,6 @@ enum ap_pwrst_trans {
|
||||||
PRCMU_AP_DEEP_IDLE = 0x07,
|
PRCMU_AP_DEEP_IDLE = 0x07,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* enum ddr_pwrst - DDR power states definition
|
|
||||||
* @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
|
|
||||||
* @DDR_PWR_STATE_ON:
|
|
||||||
* @DDR_PWR_STATE_OFFLOWLAT:
|
|
||||||
* @DDR_PWR_STATE_OFFHIGHLAT:
|
|
||||||
*/
|
|
||||||
enum ddr_pwrst {
|
|
||||||
DDR_PWR_STATE_UNCHANGED = 0x00,
|
|
||||||
DDR_PWR_STATE_ON = 0x01,
|
|
||||||
DDR_PWR_STATE_OFFLOWLAT = 0x02,
|
|
||||||
DDR_PWR_STATE_OFFHIGHLAT = 0x03
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* enum arm_opp - ARM OPP states definition
|
|
||||||
* @ARM_OPP_INIT:
|
|
||||||
* @ARM_NO_CHANGE: The ARM operating point is unchanged
|
|
||||||
* @ARM_100_OPP: The new ARM operating point is arm100opp
|
|
||||||
* @ARM_50_OPP: The new ARM operating point is arm50opp
|
|
||||||
* @ARM_MAX_OPP: Operating point is "max" (more than 100)
|
|
||||||
* @ARM_MAX_FREQ100OPP: Set max opp if available, else 100
|
|
||||||
* @ARM_EXTCLK: The new ARM operating point is armExtClk
|
|
||||||
*/
|
|
||||||
enum arm_opp {
|
|
||||||
ARM_OPP_INIT = 0x00,
|
|
||||||
ARM_NO_CHANGE = 0x01,
|
|
||||||
ARM_100_OPP = 0x02,
|
|
||||||
ARM_50_OPP = 0x03,
|
|
||||||
ARM_MAX_OPP = 0x04,
|
|
||||||
ARM_MAX_FREQ100OPP = 0x05,
|
|
||||||
ARM_EXTCLK = 0x07
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* enum ape_opp - APE OPP states definition
|
|
||||||
* @APE_OPP_INIT:
|
|
||||||
* @APE_NO_CHANGE: The APE operating point is unchanged
|
|
||||||
* @APE_100_OPP: The new APE operating point is ape100opp
|
|
||||||
* @APE_50_OPP: 50%
|
|
||||||
*/
|
|
||||||
enum ape_opp {
|
|
||||||
APE_OPP_INIT = 0x00,
|
|
||||||
APE_NO_CHANGE = 0x01,
|
|
||||||
APE_100_OPP = 0x02,
|
|
||||||
APE_50_OPP = 0x03
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum hw_acc_state - State definition for hardware accelerator
|
* enum hw_acc_state - State definition for hardware accelerator
|
||||||
* @HW_NO_CHANGE: The hardware accelerator state must remain unchanged
|
* @HW_NO_CHANGE: The hardware accelerator state must remain unchanged
|
||||||
|
@ -469,26 +420,6 @@ enum auto_enable {
|
||||||
|
|
||||||
/* End of file previously known as prcmu-fw-defs_v1.h */
|
/* End of file previously known as prcmu-fw-defs_v1.h */
|
||||||
|
|
||||||
/* PRCMU Wakeup defines */
|
|
||||||
enum prcmu_wakeup_index {
|
|
||||||
PRCMU_WAKEUP_INDEX_RTC,
|
|
||||||
PRCMU_WAKEUP_INDEX_RTT0,
|
|
||||||
PRCMU_WAKEUP_INDEX_RTT1,
|
|
||||||
PRCMU_WAKEUP_INDEX_HSI0,
|
|
||||||
PRCMU_WAKEUP_INDEX_HSI1,
|
|
||||||
PRCMU_WAKEUP_INDEX_USB,
|
|
||||||
PRCMU_WAKEUP_INDEX_ABB,
|
|
||||||
PRCMU_WAKEUP_INDEX_ABB_FIFO,
|
|
||||||
PRCMU_WAKEUP_INDEX_ARM,
|
|
||||||
NUM_PRCMU_WAKEUP_INDICES
|
|
||||||
};
|
|
||||||
#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name))
|
|
||||||
|
|
||||||
/* PRCMU QoS APE OPP class */
|
|
||||||
#define PRCMU_QOS_APE_OPP 1
|
|
||||||
#define PRCMU_QOS_DDR_OPP 2
|
|
||||||
#define PRCMU_QOS_DEFAULT_VALUE -1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum hw_acc_dev - enum for hw accelerators
|
* enum hw_acc_dev - enum for hw accelerators
|
||||||
* @HW_ACC_SVAMMDSP: for SVAMMDSP
|
* @HW_ACC_SVAMMDSP: for SVAMMDSP
|
||||||
|
@ -526,64 +457,6 @@ enum hw_acc_dev {
|
||||||
NUM_HW_ACC
|
NUM_HW_ACC
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Ids for all EPODs (power domains)
|
|
||||||
* - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP
|
|
||||||
* - EPOD_ID_SVAPIPE: power domain for SVA pipe
|
|
||||||
* - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP
|
|
||||||
* - EPOD_ID_SIAPIPE: power domain for SIA pipe
|
|
||||||
* - EPOD_ID_SGA: power domain for SGA
|
|
||||||
* - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE
|
|
||||||
* - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2
|
|
||||||
* - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4
|
|
||||||
* - NUM_EPOD_ID: number of power domains
|
|
||||||
*/
|
|
||||||
#define EPOD_ID_SVAMMDSP 0
|
|
||||||
#define EPOD_ID_SVAPIPE 1
|
|
||||||
#define EPOD_ID_SIAMMDSP 2
|
|
||||||
#define EPOD_ID_SIAPIPE 3
|
|
||||||
#define EPOD_ID_SGA 4
|
|
||||||
#define EPOD_ID_B2R2_MCDE 5
|
|
||||||
#define EPOD_ID_ESRAM12 6
|
|
||||||
#define EPOD_ID_ESRAM34 7
|
|
||||||
#define NUM_EPOD_ID 8
|
|
||||||
|
|
||||||
/*
|
|
||||||
* state definition for EPOD (power domain)
|
|
||||||
* - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged
|
|
||||||
* - EPOD_STATE_OFF: The EPOD is switched off
|
|
||||||
* - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in
|
|
||||||
* retention
|
|
||||||
* - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off
|
|
||||||
* - EPOD_STATE_ON: Same as above, but with clock enabled
|
|
||||||
*/
|
|
||||||
#define EPOD_STATE_NO_CHANGE 0x00
|
|
||||||
#define EPOD_STATE_OFF 0x01
|
|
||||||
#define EPOD_STATE_RAMRET 0x02
|
|
||||||
#define EPOD_STATE_ON_CLK_OFF 0x03
|
|
||||||
#define EPOD_STATE_ON 0x04
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CLKOUT sources
|
|
||||||
*/
|
|
||||||
#define PRCMU_CLKSRC_CLK38M 0x00
|
|
||||||
#define PRCMU_CLKSRC_ACLK 0x01
|
|
||||||
#define PRCMU_CLKSRC_SYSCLK 0x02
|
|
||||||
#define PRCMU_CLKSRC_LCDCLK 0x03
|
|
||||||
#define PRCMU_CLKSRC_SDMMCCLK 0x04
|
|
||||||
#define PRCMU_CLKSRC_TVCLK 0x05
|
|
||||||
#define PRCMU_CLKSRC_TIMCLK 0x06
|
|
||||||
#define PRCMU_CLKSRC_CLK009 0x07
|
|
||||||
/* These are only valid for CLKOUT1: */
|
|
||||||
#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40
|
|
||||||
#define PRCMU_CLKSRC_I2CCLK 0x41
|
|
||||||
#define PRCMU_CLKSRC_MSP02CLK 0x42
|
|
||||||
#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43
|
|
||||||
#define PRCMU_CLKSRC_HSIRXCLK 0x44
|
|
||||||
#define PRCMU_CLKSRC_HSITXCLK 0x45
|
|
||||||
#define PRCMU_CLKSRC_ARMCLKFIX 0x46
|
|
||||||
#define PRCMU_CLKSRC_HDMICLK 0x47
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for autonomous power management configuration.
|
* Definitions for autonomous power management configuration.
|
||||||
*/
|
*/
|
||||||
|
@ -620,88 +493,12 @@ struct prcmu_auto_pm_config {
|
||||||
u8 sva_policy;
|
u8 sva_policy;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* enum ddr_opp - DDR OPP states definition
|
|
||||||
* @DDR_100_OPP: The new DDR operating point is ddr100opp
|
|
||||||
* @DDR_50_OPP: The new DDR operating point is ddr50opp
|
|
||||||
* @DDR_25_OPP: The new DDR operating point is ddr25opp
|
|
||||||
*/
|
|
||||||
enum ddr_opp {
|
|
||||||
DDR_100_OPP = 0x00,
|
|
||||||
DDR_50_OPP = 0x01,
|
|
||||||
DDR_25_OPP = 0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clock identifiers.
|
|
||||||
*/
|
|
||||||
enum prcmu_clock {
|
|
||||||
PRCMU_SGACLK,
|
|
||||||
PRCMU_UARTCLK,
|
|
||||||
PRCMU_MSP02CLK,
|
|
||||||
PRCMU_MSP1CLK,
|
|
||||||
PRCMU_I2CCLK,
|
|
||||||
PRCMU_SDMMCCLK,
|
|
||||||
PRCMU_SLIMCLK,
|
|
||||||
PRCMU_PER1CLK,
|
|
||||||
PRCMU_PER2CLK,
|
|
||||||
PRCMU_PER3CLK,
|
|
||||||
PRCMU_PER5CLK,
|
|
||||||
PRCMU_PER6CLK,
|
|
||||||
PRCMU_PER7CLK,
|
|
||||||
PRCMU_LCDCLK,
|
|
||||||
PRCMU_BMLCLK,
|
|
||||||
PRCMU_HSITXCLK,
|
|
||||||
PRCMU_HSIRXCLK,
|
|
||||||
PRCMU_HDMICLK,
|
|
||||||
PRCMU_APEATCLK,
|
|
||||||
PRCMU_APETRACECLK,
|
|
||||||
PRCMU_MCDECLK,
|
|
||||||
PRCMU_IPI2CCLK,
|
|
||||||
PRCMU_DSIALTCLK,
|
|
||||||
PRCMU_DMACLK,
|
|
||||||
PRCMU_B2R2CLK,
|
|
||||||
PRCMU_TVCLK,
|
|
||||||
PRCMU_SSPCLK,
|
|
||||||
PRCMU_RNGCLK,
|
|
||||||
PRCMU_UICCCLK,
|
|
||||||
PRCMU_NUM_REG_CLOCKS,
|
|
||||||
PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS,
|
|
||||||
PRCMU_TIMCLK,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Definitions for controlling ESRAM0 in deep sleep.
|
|
||||||
*/
|
|
||||||
#define ESRAM0_DEEP_SLEEP_STATE_OFF 1
|
|
||||||
#define ESRAM0_DEEP_SLEEP_STATE_RET 2
|
|
||||||
|
|
||||||
#ifdef CONFIG_MFD_DB8500_PRCMU
|
|
||||||
void __init prcmu_early_init(void);
|
|
||||||
int prcmu_set_display_clocks(void);
|
|
||||||
int prcmu_disable_dsipll(void);
|
|
||||||
int prcmu_enable_dsipll(void);
|
|
||||||
#else
|
|
||||||
static inline void __init prcmu_early_init(void) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_MFD_DB8500_PRCMU
|
#ifdef CONFIG_MFD_DB8500_PRCMU
|
||||||
|
|
||||||
|
void db8500_prcmu_early_init(void);
|
||||||
int prcmu_set_rc_a2p(enum romcode_write);
|
int prcmu_set_rc_a2p(enum romcode_write);
|
||||||
enum romcode_read prcmu_get_rc_p2a(void);
|
enum romcode_read prcmu_get_rc_p2a(void);
|
||||||
enum ap_pwrst prcmu_get_xp70_current_state(void);
|
enum ap_pwrst prcmu_get_xp70_current_state(void);
|
||||||
int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll);
|
|
||||||
|
|
||||||
void prcmu_enable_wakeups(u32 wakeups);
|
|
||||||
static inline void prcmu_disable_wakeups(void)
|
|
||||||
{
|
|
||||||
prcmu_enable_wakeups(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void prcmu_config_abb_event_readout(u32 abb_events);
|
|
||||||
void prcmu_get_abb_event_buffer(void __iomem **buf);
|
|
||||||
int prcmu_set_arm_opp(u8 opp);
|
|
||||||
int prcmu_get_arm_opp(void);
|
|
||||||
bool prcmu_has_arm_maxopp(void);
|
bool prcmu_has_arm_maxopp(void);
|
||||||
bool prcmu_is_u8400(void);
|
bool prcmu_is_u8400(void);
|
||||||
int prcmu_set_ape_opp(u8 opp);
|
int prcmu_set_ape_opp(u8 opp);
|
||||||
|
@ -710,19 +507,14 @@ int prcmu_request_ape_opp_100_voltage(bool enable);
|
||||||
int prcmu_release_usb_wakeup_state(void);
|
int prcmu_release_usb_wakeup_state(void);
|
||||||
int prcmu_set_ddr_opp(u8 opp);
|
int prcmu_set_ddr_opp(u8 opp);
|
||||||
int prcmu_get_ddr_opp(void);
|
int prcmu_get_ddr_opp(void);
|
||||||
unsigned long prcmu_qos_get_cpufreq_opp_delay(void);
|
|
||||||
void prcmu_qos_set_cpufreq_opp_delay(unsigned long);
|
|
||||||
/* NOTE! Use regulator framework instead */
|
/* NOTE! Use regulator framework instead */
|
||||||
int prcmu_set_hwacc(u16 hw_acc_dev, u8 state);
|
int prcmu_set_hwacc(u16 hw_acc_dev, u8 state);
|
||||||
int prcmu_set_epod(u16 epod_id, u8 epod_state);
|
|
||||||
void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
|
void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
|
||||||
struct prcmu_auto_pm_config *idle);
|
struct prcmu_auto_pm_config *idle);
|
||||||
bool prcmu_is_auto_pm_enabled(void);
|
bool prcmu_is_auto_pm_enabled(void);
|
||||||
|
|
||||||
int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
|
int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
|
||||||
int prcmu_request_clock(u8 clock, bool enable);
|
|
||||||
int prcmu_set_clock_divider(u8 clock, u8 divider);
|
int prcmu_set_clock_divider(u8 clock, u8 divider);
|
||||||
int prcmu_config_esram0_deep_sleep(u8 state);
|
|
||||||
int prcmu_config_hotdog(u8 threshold);
|
int prcmu_config_hotdog(u8 threshold);
|
||||||
int prcmu_config_hotmon(u8 low, u8 high);
|
int prcmu_config_hotmon(u8 low, u8 high);
|
||||||
int prcmu_start_temp_sense(u16 cycles32k);
|
int prcmu_start_temp_sense(u16 cycles32k);
|
||||||
|
@ -732,14 +524,36 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||||
|
|
||||||
void prcmu_ac_wake_req(void);
|
void prcmu_ac_wake_req(void);
|
||||||
void prcmu_ac_sleep_req(void);
|
void prcmu_ac_sleep_req(void);
|
||||||
void prcmu_system_reset(u16 reset_code);
|
|
||||||
void prcmu_modem_reset(void);
|
void prcmu_modem_reset(void);
|
||||||
bool prcmu_is_ac_wake_requested(void);
|
|
||||||
void prcmu_enable_spi2(void);
|
void prcmu_enable_spi2(void);
|
||||||
void prcmu_disable_spi2(void);
|
void prcmu_disable_spi2(void);
|
||||||
|
|
||||||
|
int prcmu_config_a9wdog(u8 num, bool sleep_auto_off);
|
||||||
|
int prcmu_enable_a9wdog(u8 id);
|
||||||
|
int prcmu_disable_a9wdog(u8 id);
|
||||||
|
int prcmu_kick_a9wdog(u8 id);
|
||||||
|
int prcmu_load_a9wdog(u8 id, u32 val);
|
||||||
|
|
||||||
|
void db8500_prcmu_system_reset(u16 reset_code);
|
||||||
|
int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll);
|
||||||
|
void db8500_prcmu_enable_wakeups(u32 wakeups);
|
||||||
|
int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state);
|
||||||
|
int db8500_prcmu_request_clock(u8 clock, bool enable);
|
||||||
|
int db8500_prcmu_set_display_clocks(void);
|
||||||
|
int db8500_prcmu_disable_dsipll(void);
|
||||||
|
int db8500_prcmu_enable_dsipll(void);
|
||||||
|
void db8500_prcmu_config_abb_event_readout(u32 abb_events);
|
||||||
|
void db8500_prcmu_get_abb_event_buffer(void __iomem **buf);
|
||||||
|
int db8500_prcmu_config_esram0_deep_sleep(u8 state);
|
||||||
|
u16 db8500_prcmu_get_reset_code(void);
|
||||||
|
bool db8500_prcmu_is_ac_wake_requested(void);
|
||||||
|
int db8500_prcmu_set_arm_opp(u8 opp);
|
||||||
|
int db8500_prcmu_get_arm_opp(void);
|
||||||
|
|
||||||
#else /* !CONFIG_MFD_DB8500_PRCMU */
|
#else /* !CONFIG_MFD_DB8500_PRCMU */
|
||||||
|
|
||||||
|
static inline void db8500_prcmu_early_init(void) {}
|
||||||
|
|
||||||
static inline int prcmu_set_rc_a2p(enum romcode_write code)
|
static inline int prcmu_set_rc_a2p(enum romcode_write code)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -755,34 +569,12 @@ static inline enum ap_pwrst prcmu_get_xp70_current_state(void)
|
||||||
return AP_EXECUTE;
|
return AP_EXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
static inline bool prcmu_has_arm_maxopp(void)
|
||||||
bool keep_ap_pll)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void prcmu_enable_wakeups(u32 wakeups) {}
|
|
||||||
|
|
||||||
static inline void prcmu_disable_wakeups(void) {}
|
|
||||||
|
|
||||||
static inline void prcmu_config_abb_event_readout(u32 abb_events) {}
|
|
||||||
|
|
||||||
static inline int prcmu_set_arm_opp(u8 opp)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_get_arm_opp(void)
|
|
||||||
{
|
|
||||||
return ARM_100_OPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool prcmu_has_arm_maxopp(void)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool prcmu_is_u8400(void)
|
static inline bool prcmu_is_u8400(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -817,13 +609,6 @@ static inline int prcmu_get_ddr_opp(void)
|
||||||
return DDR_100_OPP;
|
return DDR_100_OPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {}
|
|
||||||
|
|
||||||
static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state)
|
static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -844,21 +629,11 @@ static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int prcmu_request_clock(u8 clock, bool enable)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_set_clock_divider(u8 clock, u8 divider)
|
static inline int prcmu_set_clock_divider(u8 clock, u8 divider)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prcmu_config_esram0_deep_sleep(u8 state)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_config_hotdog(u8 threshold)
|
static inline int prcmu_config_hotdog(u8 threshold)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -893,32 +668,8 @@ static inline void prcmu_ac_wake_req(void) {}
|
||||||
|
|
||||||
static inline void prcmu_ac_sleep_req(void) {}
|
static inline void prcmu_ac_sleep_req(void) {}
|
||||||
|
|
||||||
static inline void prcmu_system_reset(u16 reset_code) {}
|
|
||||||
|
|
||||||
static inline void prcmu_modem_reset(void) {}
|
static inline void prcmu_modem_reset(void) {}
|
||||||
|
|
||||||
static inline bool prcmu_is_ac_wake_requested(void)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_UX500_SOC_DB5500
|
|
||||||
static inline int prcmu_set_display_clocks(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_disable_dsipll(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_enable_dsipll(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int prcmu_enable_spi2(void)
|
static inline int prcmu_enable_spi2(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -929,50 +680,95 @@ static inline int prcmu_disable_spi2(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void db8500_prcmu_system_reset(u16 reset_code) {}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
bool keep_ap_pll)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void db8500_prcmu_enable_wakeups(u32 wakeups) {}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_request_clock(u8 clock, bool enable)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_set_display_clocks(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_disable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_enable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_config_esram0_deep_sleep(u8 state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void db8500_prcmu_config_abb_event_readout(u32 abb_events) {}
|
||||||
|
|
||||||
|
static inline void db8500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
|
||||||
|
|
||||||
|
static inline u16 db8500_prcmu_get_reset_code(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_enable_a9wdog(u8 id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_disable_a9wdog(u8 id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_kick_a9wdog(u8 id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_load_a9wdog(u8 id, u32 val)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool db8500_prcmu_is_ac_wake_requested(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_set_arm_opp(u8 opp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int db8500_prcmu_get_arm_opp(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !CONFIG_MFD_DB8500_PRCMU */
|
#endif /* !CONFIG_MFD_DB8500_PRCMU */
|
||||||
|
|
||||||
#ifdef CONFIG_UX500_PRCMU_QOS_POWER
|
|
||||||
int prcmu_qos_requirement(int pm_qos_class);
|
|
||||||
int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value);
|
|
||||||
int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value);
|
|
||||||
void prcmu_qos_remove_requirement(int pm_qos_class, char *name);
|
|
||||||
int prcmu_qos_add_notifier(int prcmu_qos_class,
|
|
||||||
struct notifier_block *notifier);
|
|
||||||
int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
|
||||||
struct notifier_block *notifier);
|
|
||||||
#else
|
|
||||||
static inline int prcmu_qos_requirement(int prcmu_qos_class)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_qos_add_requirement(int prcmu_qos_class,
|
|
||||||
char *name, s32 value)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_qos_update_requirement(int prcmu_qos_class,
|
|
||||||
char *name, s32 new_value)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int prcmu_qos_add_notifier(int prcmu_qos_class,
|
|
||||||
struct notifier_block *notifier)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static inline int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
|
||||||
struct notifier_block *notifier)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __MFD_DB8500_PRCMU_H */
|
#endif /* __MFD_DB8500_PRCMU_H */
|
||||||
|
|
|
@ -0,0 +1,549 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) ST Ericsson SA 2011
|
||||||
|
*
|
||||||
|
* License Terms: GNU General Public License v2
|
||||||
|
*
|
||||||
|
* STE Ux500 PRCMU API
|
||||||
|
*/
|
||||||
|
#ifndef __MACH_PRCMU_H
|
||||||
|
#define __MACH_PRCMU_H
|
||||||
|
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
|
||||||
|
/* PRCMU Wakeup defines */
|
||||||
|
enum prcmu_wakeup_index {
|
||||||
|
PRCMU_WAKEUP_INDEX_RTC,
|
||||||
|
PRCMU_WAKEUP_INDEX_RTT0,
|
||||||
|
PRCMU_WAKEUP_INDEX_RTT1,
|
||||||
|
PRCMU_WAKEUP_INDEX_HSI0,
|
||||||
|
PRCMU_WAKEUP_INDEX_HSI1,
|
||||||
|
PRCMU_WAKEUP_INDEX_USB,
|
||||||
|
PRCMU_WAKEUP_INDEX_ABB,
|
||||||
|
PRCMU_WAKEUP_INDEX_ABB_FIFO,
|
||||||
|
PRCMU_WAKEUP_INDEX_ARM,
|
||||||
|
PRCMU_WAKEUP_INDEX_CD_IRQ,
|
||||||
|
NUM_PRCMU_WAKEUP_INDICES
|
||||||
|
};
|
||||||
|
#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name))
|
||||||
|
|
||||||
|
/* EPOD (power domain) IDs */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DB8500 EPODs
|
||||||
|
* - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP
|
||||||
|
* - EPOD_ID_SVAPIPE: power domain for SVA pipe
|
||||||
|
* - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP
|
||||||
|
* - EPOD_ID_SIAPIPE: power domain for SIA pipe
|
||||||
|
* - EPOD_ID_SGA: power domain for SGA
|
||||||
|
* - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE
|
||||||
|
* - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2
|
||||||
|
* - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4
|
||||||
|
* - NUM_EPOD_ID: number of power domains
|
||||||
|
*
|
||||||
|
* TODO: These should be prefixed.
|
||||||
|
*/
|
||||||
|
#define EPOD_ID_SVAMMDSP 0
|
||||||
|
#define EPOD_ID_SVAPIPE 1
|
||||||
|
#define EPOD_ID_SIAMMDSP 2
|
||||||
|
#define EPOD_ID_SIAPIPE 3
|
||||||
|
#define EPOD_ID_SGA 4
|
||||||
|
#define EPOD_ID_B2R2_MCDE 5
|
||||||
|
#define EPOD_ID_ESRAM12 6
|
||||||
|
#define EPOD_ID_ESRAM34 7
|
||||||
|
#define NUM_EPOD_ID 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DB5500 EPODs
|
||||||
|
*/
|
||||||
|
#define DB5500_EPOD_ID_BASE 0x0100
|
||||||
|
#define DB5500_EPOD_ID_SGA (DB5500_EPOD_ID_BASE + 0)
|
||||||
|
#define DB5500_EPOD_ID_HVA (DB5500_EPOD_ID_BASE + 1)
|
||||||
|
#define DB5500_EPOD_ID_SIA (DB5500_EPOD_ID_BASE + 2)
|
||||||
|
#define DB5500_EPOD_ID_DISP (DB5500_EPOD_ID_BASE + 3)
|
||||||
|
#define DB5500_EPOD_ID_ESRAM12 (DB5500_EPOD_ID_BASE + 6)
|
||||||
|
#define DB5500_NUM_EPOD_ID 7
|
||||||
|
|
||||||
|
/*
|
||||||
|
* state definition for EPOD (power domain)
|
||||||
|
* - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged
|
||||||
|
* - EPOD_STATE_OFF: The EPOD is switched off
|
||||||
|
* - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in
|
||||||
|
* retention
|
||||||
|
* - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off
|
||||||
|
* - EPOD_STATE_ON: Same as above, but with clock enabled
|
||||||
|
*/
|
||||||
|
#define EPOD_STATE_NO_CHANGE 0x00
|
||||||
|
#define EPOD_STATE_OFF 0x01
|
||||||
|
#define EPOD_STATE_RAMRET 0x02
|
||||||
|
#define EPOD_STATE_ON_CLK_OFF 0x03
|
||||||
|
#define EPOD_STATE_ON 0x04
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLKOUT sources
|
||||||
|
*/
|
||||||
|
#define PRCMU_CLKSRC_CLK38M 0x00
|
||||||
|
#define PRCMU_CLKSRC_ACLK 0x01
|
||||||
|
#define PRCMU_CLKSRC_SYSCLK 0x02
|
||||||
|
#define PRCMU_CLKSRC_LCDCLK 0x03
|
||||||
|
#define PRCMU_CLKSRC_SDMMCCLK 0x04
|
||||||
|
#define PRCMU_CLKSRC_TVCLK 0x05
|
||||||
|
#define PRCMU_CLKSRC_TIMCLK 0x06
|
||||||
|
#define PRCMU_CLKSRC_CLK009 0x07
|
||||||
|
/* These are only valid for CLKOUT1: */
|
||||||
|
#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40
|
||||||
|
#define PRCMU_CLKSRC_I2CCLK 0x41
|
||||||
|
#define PRCMU_CLKSRC_MSP02CLK 0x42
|
||||||
|
#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43
|
||||||
|
#define PRCMU_CLKSRC_HSIRXCLK 0x44
|
||||||
|
#define PRCMU_CLKSRC_HSITXCLK 0x45
|
||||||
|
#define PRCMU_CLKSRC_ARMCLKFIX 0x46
|
||||||
|
#define PRCMU_CLKSRC_HDMICLK 0x47
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clock identifiers.
|
||||||
|
*/
|
||||||
|
enum prcmu_clock {
|
||||||
|
PRCMU_SGACLK,
|
||||||
|
PRCMU_UARTCLK,
|
||||||
|
PRCMU_MSP02CLK,
|
||||||
|
PRCMU_MSP1CLK,
|
||||||
|
PRCMU_I2CCLK,
|
||||||
|
PRCMU_SDMMCCLK,
|
||||||
|
PRCMU_SLIMCLK,
|
||||||
|
PRCMU_PER1CLK,
|
||||||
|
PRCMU_PER2CLK,
|
||||||
|
PRCMU_PER3CLK,
|
||||||
|
PRCMU_PER5CLK,
|
||||||
|
PRCMU_PER6CLK,
|
||||||
|
PRCMU_PER7CLK,
|
||||||
|
PRCMU_LCDCLK,
|
||||||
|
PRCMU_BMLCLK,
|
||||||
|
PRCMU_HSITXCLK,
|
||||||
|
PRCMU_HSIRXCLK,
|
||||||
|
PRCMU_HDMICLK,
|
||||||
|
PRCMU_APEATCLK,
|
||||||
|
PRCMU_APETRACECLK,
|
||||||
|
PRCMU_MCDECLK,
|
||||||
|
PRCMU_IPI2CCLK,
|
||||||
|
PRCMU_DSIALTCLK,
|
||||||
|
PRCMU_DMACLK,
|
||||||
|
PRCMU_B2R2CLK,
|
||||||
|
PRCMU_TVCLK,
|
||||||
|
PRCMU_SSPCLK,
|
||||||
|
PRCMU_RNGCLK,
|
||||||
|
PRCMU_UICCCLK,
|
||||||
|
PRCMU_PWMCLK,
|
||||||
|
PRCMU_IRDACLK,
|
||||||
|
PRCMU_IRRCCLK,
|
||||||
|
PRCMU_SIACLK,
|
||||||
|
PRCMU_SVACLK,
|
||||||
|
PRCMU_NUM_REG_CLOCKS,
|
||||||
|
PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS,
|
||||||
|
PRCMU_TIMCLK,
|
||||||
|
PRCMU_PLLSOC0,
|
||||||
|
PRCMU_PLLSOC1,
|
||||||
|
PRCMU_PLLDDR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum ape_opp - APE OPP states definition
|
||||||
|
* @APE_OPP_INIT:
|
||||||
|
* @APE_NO_CHANGE: The APE operating point is unchanged
|
||||||
|
* @APE_100_OPP: The new APE operating point is ape100opp
|
||||||
|
* @APE_50_OPP: 50%
|
||||||
|
*/
|
||||||
|
enum ape_opp {
|
||||||
|
APE_OPP_INIT = 0x00,
|
||||||
|
APE_NO_CHANGE = 0x01,
|
||||||
|
APE_100_OPP = 0x02,
|
||||||
|
APE_50_OPP = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum arm_opp - ARM OPP states definition
|
||||||
|
* @ARM_OPP_INIT:
|
||||||
|
* @ARM_NO_CHANGE: The ARM operating point is unchanged
|
||||||
|
* @ARM_100_OPP: The new ARM operating point is arm100opp
|
||||||
|
* @ARM_50_OPP: The new ARM operating point is arm50opp
|
||||||
|
* @ARM_MAX_OPP: Operating point is "max" (more than 100)
|
||||||
|
* @ARM_MAX_FREQ100OPP: Set max opp if available, else 100
|
||||||
|
* @ARM_EXTCLK: The new ARM operating point is armExtClk
|
||||||
|
*/
|
||||||
|
enum arm_opp {
|
||||||
|
ARM_OPP_INIT = 0x00,
|
||||||
|
ARM_NO_CHANGE = 0x01,
|
||||||
|
ARM_100_OPP = 0x02,
|
||||||
|
ARM_50_OPP = 0x03,
|
||||||
|
ARM_MAX_OPP = 0x04,
|
||||||
|
ARM_MAX_FREQ100OPP = 0x05,
|
||||||
|
ARM_EXTCLK = 0x07
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum ddr_opp - DDR OPP states definition
|
||||||
|
* @DDR_100_OPP: The new DDR operating point is ddr100opp
|
||||||
|
* @DDR_50_OPP: The new DDR operating point is ddr50opp
|
||||||
|
* @DDR_25_OPP: The new DDR operating point is ddr25opp
|
||||||
|
*/
|
||||||
|
enum ddr_opp {
|
||||||
|
DDR_100_OPP = 0x00,
|
||||||
|
DDR_50_OPP = 0x01,
|
||||||
|
DDR_25_OPP = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for controlling ESRAM0 in deep sleep.
|
||||||
|
*/
|
||||||
|
#define ESRAM0_DEEP_SLEEP_STATE_OFF 1
|
||||||
|
#define ESRAM0_DEEP_SLEEP_STATE_RET 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum ddr_pwrst - DDR power states definition
|
||||||
|
* @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
|
||||||
|
* @DDR_PWR_STATE_ON:
|
||||||
|
* @DDR_PWR_STATE_OFFLOWLAT:
|
||||||
|
* @DDR_PWR_STATE_OFFHIGHLAT:
|
||||||
|
*/
|
||||||
|
enum ddr_pwrst {
|
||||||
|
DDR_PWR_STATE_UNCHANGED = 0x00,
|
||||||
|
DDR_PWR_STATE_ON = 0x01,
|
||||||
|
DDR_PWR_STATE_OFFLOWLAT = 0x02,
|
||||||
|
DDR_PWR_STATE_OFFHIGHLAT = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <linux/mfd/db8500-prcmu.h>
|
||||||
|
#include <linux/mfd/db5500-prcmu.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500)
|
||||||
|
|
||||||
|
static inline void __init prcmu_early_init(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_early_init();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_early_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
bool keep_ap_pll)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_set_power_state(state, keep_ulp_clk,
|
||||||
|
keep_ap_pll);
|
||||||
|
else
|
||||||
|
return db8500_prcmu_set_power_state(state, keep_ulp_clk,
|
||||||
|
keep_ap_pll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
return db8500_prcmu_set_epod(epod_id, epod_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_enable_wakeups(u32 wakeups)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
db5500_prcmu_enable_wakeups(wakeups);
|
||||||
|
else
|
||||||
|
db8500_prcmu_enable_wakeups(wakeups);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_disable_wakeups(void)
|
||||||
|
{
|
||||||
|
prcmu_enable_wakeups(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_config_abb_event_readout(u32 abb_events)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
db5500_prcmu_config_abb_event_readout(abb_events);
|
||||||
|
else
|
||||||
|
db8500_prcmu_config_abb_event_readout(abb_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
db5500_prcmu_get_abb_event_buffer(buf);
|
||||||
|
else
|
||||||
|
db8500_prcmu_get_abb_event_buffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
||||||
|
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||||
|
|
||||||
|
int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
|
||||||
|
|
||||||
|
static inline int prcmu_request_clock(u8 clock, bool enable)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_request_clock(clock, enable);
|
||||||
|
else
|
||||||
|
return db8500_prcmu_request_clock(clock, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
int prcmu_set_ape_opp(u8 opp);
|
||||||
|
int prcmu_get_ape_opp(void);
|
||||||
|
int prcmu_set_ddr_opp(u8 opp);
|
||||||
|
int prcmu_get_ddr_opp(void);
|
||||||
|
|
||||||
|
static inline int prcmu_set_arm_opp(u8 opp)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
return db8500_prcmu_set_arm_opp(opp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_get_arm_opp(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
return db8500_prcmu_get_arm_opp();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_system_reset(u16 reset_code)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_system_reset(reset_code);
|
||||||
|
else
|
||||||
|
return db8500_prcmu_system_reset(reset_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 prcmu_get_reset_code(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_get_reset_code();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_get_reset_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
void prcmu_ac_wake_req(void);
|
||||||
|
void prcmu_ac_sleep_req(void);
|
||||||
|
void prcmu_modem_reset(void);
|
||||||
|
static inline bool prcmu_is_ac_wake_requested(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_is_ac_wake_requested();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_is_ac_wake_requested();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_display_clocks(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_set_display_clocks();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_set_display_clocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_disable_dsipll(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_disable_dsipll();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_disable_dsipll();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_enable_dsipll(void)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return db5500_prcmu_enable_dsipll();
|
||||||
|
else
|
||||||
|
return db8500_prcmu_enable_dsipll();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_config_esram0_deep_sleep(u8 state)
|
||||||
|
{
|
||||||
|
if (machine_is_u5500())
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
return db8500_prcmu_config_esram0_deep_sleep(state);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void __init prcmu_early_init(void) {}
|
||||||
|
|
||||||
|
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
bool keep_ap_pll)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_enable_wakeups(u32 wakeups) {}
|
||||||
|
|
||||||
|
static inline void prcmu_disable_wakeups(void) {}
|
||||||
|
|
||||||
|
static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_request_clock(u8 clock, bool enable)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_ape_opp(u8 opp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_get_ape_opp(void)
|
||||||
|
{
|
||||||
|
return APE_100_OPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_arm_opp(u8 opp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_get_arm_opp(void)
|
||||||
|
{
|
||||||
|
return ARM_100_OPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_ddr_opp(u8 opp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_get_ddr_opp(void)
|
||||||
|
{
|
||||||
|
return DDR_100_OPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_system_reset(u16 reset_code) {}
|
||||||
|
|
||||||
|
static inline u16 prcmu_get_reset_code(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_ac_wake_req(void) {}
|
||||||
|
|
||||||
|
static inline void prcmu_ac_sleep_req(void) {}
|
||||||
|
|
||||||
|
static inline void prcmu_modem_reset(void) {}
|
||||||
|
|
||||||
|
static inline bool prcmu_is_ac_wake_requested(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_set_display_clocks(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_disable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_enable_dsipll(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_config_esram0_deep_sleep(u8 state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_config_abb_event_readout(u32 abb_events) {}
|
||||||
|
|
||||||
|
static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
|
||||||
|
{
|
||||||
|
*buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* PRCMU QoS APE OPP class */
|
||||||
|
#define PRCMU_QOS_APE_OPP 1
|
||||||
|
#define PRCMU_QOS_DDR_OPP 2
|
||||||
|
#define PRCMU_QOS_DEFAULT_VALUE -1
|
||||||
|
|
||||||
|
#ifdef CONFIG_UX500_PRCMU_QOS_POWER
|
||||||
|
|
||||||
|
unsigned long prcmu_qos_get_cpufreq_opp_delay(void);
|
||||||
|
void prcmu_qos_set_cpufreq_opp_delay(unsigned long);
|
||||||
|
void prcmu_qos_force_opp(int, s32);
|
||||||
|
int prcmu_qos_requirement(int pm_qos_class);
|
||||||
|
int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value);
|
||||||
|
int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value);
|
||||||
|
void prcmu_qos_remove_requirement(int pm_qos_class, char *name);
|
||||||
|
int prcmu_qos_add_notifier(int prcmu_qos_class,
|
||||||
|
struct notifier_block *notifier);
|
||||||
|
int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
||||||
|
struct notifier_block *notifier);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {}
|
||||||
|
|
||||||
|
static inline void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) {}
|
||||||
|
|
||||||
|
static inline int prcmu_qos_requirement(int prcmu_qos_class)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_qos_add_requirement(int prcmu_qos_class,
|
||||||
|
char *name, s32 value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_qos_update_requirement(int prcmu_qos_class,
|
||||||
|
char *name, s32 new_value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int prcmu_qos_add_notifier(int prcmu_qos_class,
|
||||||
|
struct notifier_block *notifier)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
||||||
|
struct notifier_block *notifier)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MACH_PRCMU_H */
|
|
@ -0,0 +1,456 @@
|
||||||
|
/*
|
||||||
|
* include/linux/mfd/intel_msic.h - Core interface for Intel MSIC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011, Intel Corporation
|
||||||
|
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LINUX_MFD_INTEL_MSIC_H__
|
||||||
|
#define __LINUX_MFD_INTEL_MSIC_H__
|
||||||
|
|
||||||
|
/* ID */
|
||||||
|
#define INTEL_MSIC_ID0 0x000 /* RO */
|
||||||
|
#define INTEL_MSIC_ID1 0x001 /* RO */
|
||||||
|
|
||||||
|
/* IRQ */
|
||||||
|
#define INTEL_MSIC_IRQLVL1 0x002
|
||||||
|
#define INTEL_MSIC_ADC1INT 0x003
|
||||||
|
#define INTEL_MSIC_CCINT 0x004
|
||||||
|
#define INTEL_MSIC_PWRSRCINT 0x005
|
||||||
|
#define INTEL_MSIC_PWRSRCINT1 0x006
|
||||||
|
#define INTEL_MSIC_CHRINT 0x007
|
||||||
|
#define INTEL_MSIC_CHRINT1 0x008
|
||||||
|
#define INTEL_MSIC_RTCIRQ 0x009
|
||||||
|
#define INTEL_MSIC_GPIO0LVIRQ 0x00a
|
||||||
|
#define INTEL_MSIC_GPIO1LVIRQ 0x00b
|
||||||
|
#define INTEL_MSIC_GPIOHVIRQ 0x00c
|
||||||
|
#define INTEL_MSIC_VRINT 0x00d
|
||||||
|
#define INTEL_MSIC_OCAUDIO 0x00e
|
||||||
|
#define INTEL_MSIC_ACCDET 0x00f
|
||||||
|
#define INTEL_MSIC_RESETIRQ1 0x010
|
||||||
|
#define INTEL_MSIC_RESETIRQ2 0x011
|
||||||
|
#define INTEL_MSIC_MADC1INT 0x012
|
||||||
|
#define INTEL_MSIC_MCCINT 0x013
|
||||||
|
#define INTEL_MSIC_MPWRSRCINT 0x014
|
||||||
|
#define INTEL_MSIC_MPWRSRCINT1 0x015
|
||||||
|
#define INTEL_MSIC_MCHRINT 0x016
|
||||||
|
#define INTEL_MSIC_MCHRINT1 0x017
|
||||||
|
#define INTEL_MSIC_RTCIRQMASK 0x018
|
||||||
|
#define INTEL_MSIC_GPIO0LVIRQMASK 0x019
|
||||||
|
#define INTEL_MSIC_GPIO1LVIRQMASK 0x01a
|
||||||
|
#define INTEL_MSIC_GPIOHVIRQMASK 0x01b
|
||||||
|
#define INTEL_MSIC_VRINTMASK 0x01c
|
||||||
|
#define INTEL_MSIC_OCAUDIOMASK 0x01d
|
||||||
|
#define INTEL_MSIC_ACCDETMASK 0x01e
|
||||||
|
#define INTEL_MSIC_RESETIRQ1MASK 0x01f
|
||||||
|
#define INTEL_MSIC_RESETIRQ2MASK 0x020
|
||||||
|
#define INTEL_MSIC_IRQLVL1MSK 0x021
|
||||||
|
#define INTEL_MSIC_PBCONFIG 0x03e
|
||||||
|
#define INTEL_MSIC_PBSTATUS 0x03f /* RO */
|
||||||
|
|
||||||
|
/* GPIO */
|
||||||
|
#define INTEL_MSIC_GPIO0LV7CTLO 0x040
|
||||||
|
#define INTEL_MSIC_GPIO0LV6CTLO 0x041
|
||||||
|
#define INTEL_MSIC_GPIO0LV5CTLO 0x042
|
||||||
|
#define INTEL_MSIC_GPIO0LV4CTLO 0x043
|
||||||
|
#define INTEL_MSIC_GPIO0LV3CTLO 0x044
|
||||||
|
#define INTEL_MSIC_GPIO0LV2CTLO 0x045
|
||||||
|
#define INTEL_MSIC_GPIO0LV1CTLO 0x046
|
||||||
|
#define INTEL_MSIC_GPIO0LV0CTLO 0x047
|
||||||
|
#define INTEL_MSIC_GPIO1LV7CTLOS 0x048
|
||||||
|
#define INTEL_MSIC_GPIO1LV6CTLO 0x049
|
||||||
|
#define INTEL_MSIC_GPIO1LV5CTLO 0x04a
|
||||||
|
#define INTEL_MSIC_GPIO1LV4CTLO 0x04b
|
||||||
|
#define INTEL_MSIC_GPIO1LV3CTLO 0x04c
|
||||||
|
#define INTEL_MSIC_GPIO1LV2CTLO 0x04d
|
||||||
|
#define INTEL_MSIC_GPIO1LV1CTLO 0x04e
|
||||||
|
#define INTEL_MSIC_GPIO1LV0CTLO 0x04f
|
||||||
|
#define INTEL_MSIC_GPIO0LV7CTLI 0x050
|
||||||
|
#define INTEL_MSIC_GPIO0LV6CTLI 0x051
|
||||||
|
#define INTEL_MSIC_GPIO0LV5CTLI 0x052
|
||||||
|
#define INTEL_MSIC_GPIO0LV4CTLI 0x053
|
||||||
|
#define INTEL_MSIC_GPIO0LV3CTLI 0x054
|
||||||
|
#define INTEL_MSIC_GPIO0LV2CTLI 0x055
|
||||||
|
#define INTEL_MSIC_GPIO0LV1CTLI 0x056
|
||||||
|
#define INTEL_MSIC_GPIO0LV0CTLI 0x057
|
||||||
|
#define INTEL_MSIC_GPIO1LV7CTLIS 0x058
|
||||||
|
#define INTEL_MSIC_GPIO1LV6CTLI 0x059
|
||||||
|
#define INTEL_MSIC_GPIO1LV5CTLI 0x05a
|
||||||
|
#define INTEL_MSIC_GPIO1LV4CTLI 0x05b
|
||||||
|
#define INTEL_MSIC_GPIO1LV3CTLI 0x05c
|
||||||
|
#define INTEL_MSIC_GPIO1LV2CTLI 0x05d
|
||||||
|
#define INTEL_MSIC_GPIO1LV1CTLI 0x05e
|
||||||
|
#define INTEL_MSIC_GPIO1LV0CTLI 0x05f
|
||||||
|
#define INTEL_MSIC_PWM0CLKDIV1 0x061
|
||||||
|
#define INTEL_MSIC_PWM0CLKDIV0 0x062
|
||||||
|
#define INTEL_MSIC_PWM1CLKDIV1 0x063
|
||||||
|
#define INTEL_MSIC_PWM1CLKDIV0 0x064
|
||||||
|
#define INTEL_MSIC_PWM2CLKDIV1 0x065
|
||||||
|
#define INTEL_MSIC_PWM2CLKDIV0 0x066
|
||||||
|
#define INTEL_MSIC_PWM0DUTYCYCLE 0x067
|
||||||
|
#define INTEL_MSIC_PWM1DUTYCYCLE 0x068
|
||||||
|
#define INTEL_MSIC_PWM2DUTYCYCLE 0x069
|
||||||
|
#define INTEL_MSIC_GPIO0HV3CTLO 0x06d
|
||||||
|
#define INTEL_MSIC_GPIO0HV2CTLO 0x06e
|
||||||
|
#define INTEL_MSIC_GPIO0HV1CTLO 0x06f
|
||||||
|
#define INTEL_MSIC_GPIO0HV0CTLO 0x070
|
||||||
|
#define INTEL_MSIC_GPIO1HV3CTLO 0x071
|
||||||
|
#define INTEL_MSIC_GPIO1HV2CTLO 0x072
|
||||||
|
#define INTEL_MSIC_GPIO1HV1CTLO 0x073
|
||||||
|
#define INTEL_MSIC_GPIO1HV0CTLO 0x074
|
||||||
|
#define INTEL_MSIC_GPIO0HV3CTLI 0x075
|
||||||
|
#define INTEL_MSIC_GPIO0HV2CTLI 0x076
|
||||||
|
#define INTEL_MSIC_GPIO0HV1CTLI 0x077
|
||||||
|
#define INTEL_MSIC_GPIO0HV0CTLI 0x078
|
||||||
|
#define INTEL_MSIC_GPIO1HV3CTLI 0x079
|
||||||
|
#define INTEL_MSIC_GPIO1HV2CTLI 0x07a
|
||||||
|
#define INTEL_MSIC_GPIO1HV1CTLI 0x07b
|
||||||
|
#define INTEL_MSIC_GPIO1HV0CTLI 0x07c
|
||||||
|
|
||||||
|
/* SVID */
|
||||||
|
#define INTEL_MSIC_SVIDCTRL0 0x080
|
||||||
|
#define INTEL_MSIC_SVIDCTRL1 0x081
|
||||||
|
#define INTEL_MSIC_SVIDCTRL2 0x082
|
||||||
|
#define INTEL_MSIC_SVIDTXLASTPKT3 0x083 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDTXLASTPKT2 0x084 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDTXLASTPKT1 0x085 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDTXLASTPKT0 0x086 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDPKTOUTBYTE3 0x087
|
||||||
|
#define INTEL_MSIC_SVIDPKTOUTBYTE2 0x088
|
||||||
|
#define INTEL_MSIC_SVIDPKTOUTBYTE1 0x089
|
||||||
|
#define INTEL_MSIC_SVIDPKTOUTBYTE0 0x08a
|
||||||
|
#define INTEL_MSIC_SVIDRXVPDEBUG1 0x08b
|
||||||
|
#define INTEL_MSIC_SVIDRXVPDEBUG0 0x08c
|
||||||
|
#define INTEL_MSIC_SVIDRXLASTPKT3 0x08d /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXLASTPKT2 0x08e /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXLASTPKT1 0x08f /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXLASTPKT0 0x090 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXCHKSTATUS3 0x091 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXCHKSTATUS2 0x092 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXCHKSTATUS1 0x093 /* RO */
|
||||||
|
#define INTEL_MSIC_SVIDRXCHKSTATUS0 0x094 /* RO */
|
||||||
|
|
||||||
|
/* VREG */
|
||||||
|
#define INTEL_MSIC_VCCLATCH 0x0c0
|
||||||
|
#define INTEL_MSIC_VNNLATCH 0x0c1
|
||||||
|
#define INTEL_MSIC_VCCCNT 0x0c2
|
||||||
|
#define INTEL_MSIC_SMPSRAMP 0x0c3
|
||||||
|
#define INTEL_MSIC_VNNCNT 0x0c4
|
||||||
|
#define INTEL_MSIC_VNNAONCNT 0x0c5
|
||||||
|
#define INTEL_MSIC_VCC122AONCNT 0x0c6
|
||||||
|
#define INTEL_MSIC_V180AONCNT 0x0c7
|
||||||
|
#define INTEL_MSIC_V500CNT 0x0c8
|
||||||
|
#define INTEL_MSIC_VIHFCNT 0x0c9
|
||||||
|
#define INTEL_MSIC_LDORAMP1 0x0ca
|
||||||
|
#define INTEL_MSIC_LDORAMP2 0x0cb
|
||||||
|
#define INTEL_MSIC_VCC108AONCNT 0x0cc
|
||||||
|
#define INTEL_MSIC_VCC108ASCNT 0x0cd
|
||||||
|
#define INTEL_MSIC_VCC108CNT 0x0ce
|
||||||
|
#define INTEL_MSIC_VCCA100ASCNT 0x0cf
|
||||||
|
#define INTEL_MSIC_VCCA100CNT 0x0d0
|
||||||
|
#define INTEL_MSIC_VCC180AONCNT 0x0d1
|
||||||
|
#define INTEL_MSIC_VCC180CNT 0x0d2
|
||||||
|
#define INTEL_MSIC_VCC330CNT 0x0d3
|
||||||
|
#define INTEL_MSIC_VUSB330CNT 0x0d4
|
||||||
|
#define INTEL_MSIC_VCCSDIOCNT 0x0d5
|
||||||
|
#define INTEL_MSIC_VPROG1CNT 0x0d6
|
||||||
|
#define INTEL_MSIC_VPROG2CNT 0x0d7
|
||||||
|
#define INTEL_MSIC_VEMMCSCNT 0x0d8
|
||||||
|
#define INTEL_MSIC_VEMMC1CNT 0x0d9
|
||||||
|
#define INTEL_MSIC_VEMMC2CNT 0x0da
|
||||||
|
#define INTEL_MSIC_VAUDACNT 0x0db
|
||||||
|
#define INTEL_MSIC_VHSPCNT 0x0dc
|
||||||
|
#define INTEL_MSIC_VHSNCNT 0x0dd
|
||||||
|
#define INTEL_MSIC_VHDMICNT 0x0de
|
||||||
|
#define INTEL_MSIC_VOTGCNT 0x0df
|
||||||
|
#define INTEL_MSIC_V1P35CNT 0x0e0
|
||||||
|
#define INTEL_MSIC_V330AONCNT 0x0e1
|
||||||
|
|
||||||
|
/* RESET */
|
||||||
|
#define INTEL_MSIC_CHIPCNTRL 0x100 /* WO */
|
||||||
|
#define INTEL_MSIC_ERCONFIG 0x101
|
||||||
|
|
||||||
|
/* BURST */
|
||||||
|
#define INTEL_MSIC_BATCURRENTLIMIT12 0x102
|
||||||
|
#define INTEL_MSIC_BATTIMELIMIT12 0x103
|
||||||
|
#define INTEL_MSIC_BATTIMELIMIT3 0x104
|
||||||
|
#define INTEL_MSIC_BATTIMEDB 0x105
|
||||||
|
#define INTEL_MSIC_BRSTCONFIGOUTPUTS 0x106
|
||||||
|
#define INTEL_MSIC_BRSTCONFIGACTIONS 0x107
|
||||||
|
#define INTEL_MSIC_BURSTCONTROLSTATUS 0x108
|
||||||
|
|
||||||
|
/* RTC */
|
||||||
|
#define INTEL_MSIC_RTCB1 0x140 /* RO */
|
||||||
|
#define INTEL_MSIC_RTCB2 0x141 /* RO */
|
||||||
|
#define INTEL_MSIC_RTCB3 0x142 /* RO */
|
||||||
|
#define INTEL_MSIC_RTCB4 0x143 /* RO */
|
||||||
|
#define INTEL_MSIC_RTCOB1 0x144
|
||||||
|
#define INTEL_MSIC_RTCOB2 0x145
|
||||||
|
#define INTEL_MSIC_RTCOB3 0x146
|
||||||
|
#define INTEL_MSIC_RTCOB4 0x147
|
||||||
|
#define INTEL_MSIC_RTCAB1 0x148
|
||||||
|
#define INTEL_MSIC_RTCAB2 0x149
|
||||||
|
#define INTEL_MSIC_RTCAB3 0x14a
|
||||||
|
#define INTEL_MSIC_RTCAB4 0x14b
|
||||||
|
#define INTEL_MSIC_RTCWAB1 0x14c
|
||||||
|
#define INTEL_MSIC_RTCWAB2 0x14d
|
||||||
|
#define INTEL_MSIC_RTCWAB3 0x14e
|
||||||
|
#define INTEL_MSIC_RTCWAB4 0x14f
|
||||||
|
#define INTEL_MSIC_RTCSC1 0x150
|
||||||
|
#define INTEL_MSIC_RTCSC2 0x151
|
||||||
|
#define INTEL_MSIC_RTCSC3 0x152
|
||||||
|
#define INTEL_MSIC_RTCSC4 0x153
|
||||||
|
#define INTEL_MSIC_RTCSTATUS 0x154 /* RO */
|
||||||
|
#define INTEL_MSIC_RTCCONFIG1 0x155
|
||||||
|
#define INTEL_MSIC_RTCCONFIG2 0x156
|
||||||
|
|
||||||
|
/* CHARGER */
|
||||||
|
#define INTEL_MSIC_BDTIMER 0x180
|
||||||
|
#define INTEL_MSIC_BATTRMV 0x181
|
||||||
|
#define INTEL_MSIC_VBUSDET 0x182
|
||||||
|
#define INTEL_MSIC_VBUSDET1 0x183
|
||||||
|
#define INTEL_MSIC_ADPHVDET 0x184
|
||||||
|
#define INTEL_MSIC_ADPLVDET 0x185
|
||||||
|
#define INTEL_MSIC_ADPDETDBDM 0x186
|
||||||
|
#define INTEL_MSIC_LOWBATTDET 0x187
|
||||||
|
#define INTEL_MSIC_CHRCTRL 0x188
|
||||||
|
#define INTEL_MSIC_CHRCVOLTAGE 0x189
|
||||||
|
#define INTEL_MSIC_CHRCCURRENT 0x18a
|
||||||
|
#define INTEL_MSIC_SPCHARGER 0x18b
|
||||||
|
#define INTEL_MSIC_CHRTTIME 0x18c
|
||||||
|
#define INTEL_MSIC_CHRCTRL1 0x18d
|
||||||
|
#define INTEL_MSIC_PWRSRCLMT 0x18e
|
||||||
|
#define INTEL_MSIC_CHRSTWDT 0x18f
|
||||||
|
#define INTEL_MSIC_WDTWRITE 0x190 /* WO */
|
||||||
|
#define INTEL_MSIC_CHRSAFELMT 0x191
|
||||||
|
#define INTEL_MSIC_SPWRSRCINT 0x192 /* RO */
|
||||||
|
#define INTEL_MSIC_SPWRSRCINT1 0x193 /* RO */
|
||||||
|
#define INTEL_MSIC_CHRLEDPWM 0x194
|
||||||
|
#define INTEL_MSIC_CHRLEDCTRL 0x195
|
||||||
|
|
||||||
|
/* ADC */
|
||||||
|
#define INTEL_MSIC_ADC1CNTL1 0x1c0
|
||||||
|
#define INTEL_MSIC_ADC1CNTL2 0x1c1
|
||||||
|
#define INTEL_MSIC_ADC1CNTL3 0x1c2
|
||||||
|
#define INTEL_MSIC_ADC1OFFSETH 0x1c3 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1OFFSETL 0x1c4 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1ADDR0 0x1c5
|
||||||
|
#define INTEL_MSIC_ADC1ADDR1 0x1c6
|
||||||
|
#define INTEL_MSIC_ADC1ADDR2 0x1c7
|
||||||
|
#define INTEL_MSIC_ADC1ADDR3 0x1c8
|
||||||
|
#define INTEL_MSIC_ADC1ADDR4 0x1c9
|
||||||
|
#define INTEL_MSIC_ADC1ADDR5 0x1ca
|
||||||
|
#define INTEL_MSIC_ADC1ADDR6 0x1cb
|
||||||
|
#define INTEL_MSIC_ADC1ADDR7 0x1cc
|
||||||
|
#define INTEL_MSIC_ADC1ADDR8 0x1cd
|
||||||
|
#define INTEL_MSIC_ADC1ADDR9 0x1ce
|
||||||
|
#define INTEL_MSIC_ADC1ADDR10 0x1cf
|
||||||
|
#define INTEL_MSIC_ADC1ADDR11 0x1d0
|
||||||
|
#define INTEL_MSIC_ADC1ADDR12 0x1d1
|
||||||
|
#define INTEL_MSIC_ADC1ADDR13 0x1d2
|
||||||
|
#define INTEL_MSIC_ADC1ADDR14 0x1d3
|
||||||
|
#define INTEL_MSIC_ADC1SNS0H 0x1d4 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS0L 0x1d5 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS1H 0x1d6 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS1L 0x1d7 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS2H 0x1d8 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS2L 0x1d9 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS3H 0x1da /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS3L 0x1db /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS4H 0x1dc /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS4L 0x1dd /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS5H 0x1de /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS5L 0x1df /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS6H 0x1e0 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS6L 0x1e1 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS7H 0x1e2 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS7L 0x1e3 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS8H 0x1e4 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS8L 0x1e5 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS9H 0x1e6 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS9L 0x1e7 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS10H 0x1e8 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS10L 0x1e9 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS11H 0x1ea /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS11L 0x1eb /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS12H 0x1ec /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS12L 0x1ed /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS13H 0x1ee /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS13L 0x1ef /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS14H 0x1f0 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1SNS14L 0x1f1 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV0H 0x1f2 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV0L 0x1f3 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV1H 0x1f4 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV1L 0x1f5 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV2H 0x1f6 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV2L 0x1f7 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV3H 0x1f8 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BV3L 0x1f9 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI0H 0x1fa /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI0L 0x1fb /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI1H 0x1fc /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI1L 0x1fd /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI2H 0x1fe /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI2L 0x1ff /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI3H 0x200 /* RO */
|
||||||
|
#define INTEL_MSIC_ADC1BI3L 0x201 /* RO */
|
||||||
|
#define INTEL_MSIC_CCCNTL 0x202
|
||||||
|
#define INTEL_MSIC_CCOFFSETH 0x203 /* RO */
|
||||||
|
#define INTEL_MSIC_CCOFFSETL 0x204 /* RO */
|
||||||
|
#define INTEL_MSIC_CCADCHA 0x205 /* RO */
|
||||||
|
#define INTEL_MSIC_CCADCLA 0x206 /* RO */
|
||||||
|
|
||||||
|
/* AUDIO */
|
||||||
|
#define INTEL_MSIC_AUDPLLCTRL 0x240
|
||||||
|
#define INTEL_MSIC_DMICBUF0123 0x241
|
||||||
|
#define INTEL_MSIC_DMICBUF45 0x242
|
||||||
|
#define INTEL_MSIC_DMICGPO 0x244
|
||||||
|
#define INTEL_MSIC_DMICMUX 0x245
|
||||||
|
#define INTEL_MSIC_DMICCLK 0x246
|
||||||
|
#define INTEL_MSIC_MICBIAS 0x247
|
||||||
|
#define INTEL_MSIC_ADCCONFIG 0x248
|
||||||
|
#define INTEL_MSIC_MICAMP1 0x249
|
||||||
|
#define INTEL_MSIC_MICAMP2 0x24a
|
||||||
|
#define INTEL_MSIC_NOISEMUX 0x24b
|
||||||
|
#define INTEL_MSIC_AUDIOMUX12 0x24c
|
||||||
|
#define INTEL_MSIC_AUDIOMUX34 0x24d
|
||||||
|
#define INTEL_MSIC_AUDIOSINC 0x24e
|
||||||
|
#define INTEL_MSIC_AUDIOTXEN 0x24f
|
||||||
|
#define INTEL_MSIC_HSEPRXCTRL 0x250
|
||||||
|
#define INTEL_MSIC_IHFRXCTRL 0x251
|
||||||
|
#define INTEL_MSIC_VOICETXVOL 0x252
|
||||||
|
#define INTEL_MSIC_SIDETONEVOL 0x253
|
||||||
|
#define INTEL_MSIC_MUSICSHARVOL 0x254
|
||||||
|
#define INTEL_MSIC_VOICETXCTRL 0x255
|
||||||
|
#define INTEL_MSIC_HSMIXER 0x256
|
||||||
|
#define INTEL_MSIC_DACCONFIG 0x257
|
||||||
|
#define INTEL_MSIC_SOFTMUTE 0x258
|
||||||
|
#define INTEL_MSIC_HSLVOLCTRL 0x259
|
||||||
|
#define INTEL_MSIC_HSRVOLCTRL 0x25a
|
||||||
|
#define INTEL_MSIC_IHFLVOLCTRL 0x25b
|
||||||
|
#define INTEL_MSIC_IHFRVOLCTRL 0x25c
|
||||||
|
#define INTEL_MSIC_DRIVEREN 0x25d
|
||||||
|
#define INTEL_MSIC_LINEOUTCTRL 0x25e
|
||||||
|
#define INTEL_MSIC_VIB1CTRL1 0x25f
|
||||||
|
#define INTEL_MSIC_VIB1CTRL2 0x260
|
||||||
|
#define INTEL_MSIC_VIB1CTRL3 0x261
|
||||||
|
#define INTEL_MSIC_VIB1SPIPCM_1 0x262
|
||||||
|
#define INTEL_MSIC_VIB1SPIPCM_2 0x263
|
||||||
|
#define INTEL_MSIC_VIB1CTRL5 0x264
|
||||||
|
#define INTEL_MSIC_VIB2CTRL1 0x265
|
||||||
|
#define INTEL_MSIC_VIB2CTRL2 0x266
|
||||||
|
#define INTEL_MSIC_VIB2CTRL3 0x267
|
||||||
|
#define INTEL_MSIC_VIB2SPIPCM_1 0x268
|
||||||
|
#define INTEL_MSIC_VIB2SPIPCM_2 0x269
|
||||||
|
#define INTEL_MSIC_VIB2CTRL5 0x26a
|
||||||
|
#define INTEL_MSIC_BTNCTRL1 0x26b
|
||||||
|
#define INTEL_MSIC_BTNCTRL2 0x26c
|
||||||
|
#define INTEL_MSIC_PCM1TXSLOT01 0x26d
|
||||||
|
#define INTEL_MSIC_PCM1TXSLOT23 0x26e
|
||||||
|
#define INTEL_MSIC_PCM1TXSLOT45 0x26f
|
||||||
|
#define INTEL_MSIC_PCM1RXSLOT0123 0x270
|
||||||
|
#define INTEL_MSIC_PCM1RXSLOT045 0x271
|
||||||
|
#define INTEL_MSIC_PCM2TXSLOT01 0x272
|
||||||
|
#define INTEL_MSIC_PCM2TXSLOT23 0x273
|
||||||
|
#define INTEL_MSIC_PCM2TXSLOT45 0x274
|
||||||
|
#define INTEL_MSIC_PCM2RXSLOT01 0x275
|
||||||
|
#define INTEL_MSIC_PCM2RXSLOT23 0x276
|
||||||
|
#define INTEL_MSIC_PCM2RXSLOT45 0x277
|
||||||
|
#define INTEL_MSIC_PCM1CTRL1 0x278
|
||||||
|
#define INTEL_MSIC_PCM1CTRL2 0x279
|
||||||
|
#define INTEL_MSIC_PCM1CTRL3 0x27a
|
||||||
|
#define INTEL_MSIC_PCM2CTRL1 0x27b
|
||||||
|
#define INTEL_MSIC_PCM2CTRL2 0x27c
|
||||||
|
|
||||||
|
/* HDMI */
|
||||||
|
#define INTEL_MSIC_HDMIPUEN 0x280
|
||||||
|
#define INTEL_MSIC_HDMISTATUS 0x281 /* RO */
|
||||||
|
|
||||||
|
/* Physical address of the start of the MSIC interrupt tree in SRAM */
|
||||||
|
#define INTEL_MSIC_IRQ_PHYS_BASE 0xffff7fc0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct intel_msic_gpio_pdata - platform data for the MSIC GPIO driver
|
||||||
|
* @gpio_base: base number for the GPIOs
|
||||||
|
*/
|
||||||
|
struct intel_msic_gpio_pdata {
|
||||||
|
unsigned gpio_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct intel_msic_ocd_pdata - platform data for the MSIC OCD driver
|
||||||
|
* @gpio: GPIO number used for OCD interrupts
|
||||||
|
*
|
||||||
|
* The MSIC MFD driver converts @gpio into an IRQ number and passes it to
|
||||||
|
* the OCD driver as %IORESOURCE_IRQ.
|
||||||
|
*/
|
||||||
|
struct intel_msic_ocd_pdata {
|
||||||
|
unsigned gpio;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MSIC embedded blocks (subdevices) */
|
||||||
|
enum intel_msic_block {
|
||||||
|
INTEL_MSIC_BLOCK_TOUCH,
|
||||||
|
INTEL_MSIC_BLOCK_ADC,
|
||||||
|
INTEL_MSIC_BLOCK_BATTERY,
|
||||||
|
INTEL_MSIC_BLOCK_GPIO,
|
||||||
|
INTEL_MSIC_BLOCK_AUDIO,
|
||||||
|
INTEL_MSIC_BLOCK_HDMI,
|
||||||
|
INTEL_MSIC_BLOCK_THERMAL,
|
||||||
|
INTEL_MSIC_BLOCK_POWER_BTN,
|
||||||
|
INTEL_MSIC_BLOCK_OCD,
|
||||||
|
|
||||||
|
INTEL_MSIC_BLOCK_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct intel_msic_platform_data - platform data for the MSIC driver
|
||||||
|
* @irq: array of interrupt numbers, one per device. If @irq is set to %0
|
||||||
|
* for a given block, the corresponding platform device is not
|
||||||
|
* created. For devices which don't have an interrupt, use %0xff
|
||||||
|
* (this is same as in SFI spec).
|
||||||
|
* @gpio: platform data for the MSIC GPIO driver
|
||||||
|
* @ocd: platform data for the MSIC OCD driver
|
||||||
|
*
|
||||||
|
* Once the MSIC driver is initialized, the register interface is ready to
|
||||||
|
* use. All the platform devices for subdevices are created after the
|
||||||
|
* register interface is ready so that we can guarantee its availability to
|
||||||
|
* the subdevice drivers.
|
||||||
|
*
|
||||||
|
* Interrupt numbers are passed to the subdevices via %IORESOURCE_IRQ
|
||||||
|
* resources of the created platform device.
|
||||||
|
*/
|
||||||
|
struct intel_msic_platform_data {
|
||||||
|
int irq[INTEL_MSIC_BLOCK_LAST];
|
||||||
|
struct intel_msic_gpio_pdata *gpio;
|
||||||
|
struct intel_msic_ocd_pdata *ocd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intel_msic;
|
||||||
|
|
||||||
|
extern int intel_msic_reg_read(unsigned short reg, u8 *val);
|
||||||
|
extern int intel_msic_reg_write(unsigned short reg, u8 val);
|
||||||
|
extern int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask);
|
||||||
|
extern int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count);
|
||||||
|
extern int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pdev_to_intel_msic - gets an MSIC instance from the platform device
|
||||||
|
* @pdev: platform device pointer
|
||||||
|
*
|
||||||
|
* The client drivers need to have pointer to the MSIC instance if they
|
||||||
|
* want to call intel_msic_irq_read(). This macro can be used for
|
||||||
|
* convenience to get the MSIC pointer from @pdev where needed. This is
|
||||||
|
* _only_ valid for devices which are managed by the MSIC.
|
||||||
|
*/
|
||||||
|
#define pdev_to_intel_msic(pdev) (dev_get_drvdata(pdev->dev.parent))
|
||||||
|
|
||||||
|
extern int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg,
|
||||||
|
u8 *val);
|
||||||
|
|
||||||
|
#endif /* __LINUX_MFD_INTEL_MSIC_H__ */
|
|
@ -326,7 +326,6 @@ struct max8997_dev {
|
||||||
int irq;
|
int irq;
|
||||||
int ono;
|
int ono;
|
||||||
int irq_base;
|
int irq_base;
|
||||||
bool wakeup;
|
|
||||||
struct mutex irqlock;
|
struct mutex irqlock;
|
||||||
int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
|
int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
|
||||||
int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
|
int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
|
||||||
|
|
|
@ -12,117 +12,6 @@
|
||||||
|
|
||||||
#include <linux/mfd/mc13xxx.h>
|
#include <linux/mfd/mc13xxx.h>
|
||||||
|
|
||||||
struct mc13783;
|
|
||||||
|
|
||||||
struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783);
|
|
||||||
|
|
||||||
static inline void mc13783_lock(struct mc13783 *mc13783)
|
|
||||||
{
|
|
||||||
mc13xxx_lock(mc13783_to_mc13xxx(mc13783));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mc13783_unlock(struct mc13783 *mc13783)
|
|
||||||
{
|
|
||||||
mc13xxx_unlock(mc13783_to_mc13xxx(mc13783));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_reg_read(struct mc13783 *mc13783,
|
|
||||||
unsigned int offset, u32 *val)
|
|
||||||
{
|
|
||||||
return mc13xxx_reg_read(mc13783_to_mc13xxx(mc13783), offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_reg_write(struct mc13783 *mc13783,
|
|
||||||
unsigned int offset, u32 val)
|
|
||||||
{
|
|
||||||
return mc13xxx_reg_write(mc13783_to_mc13xxx(mc13783), offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_reg_rmw(struct mc13783 *mc13783,
|
|
||||||
unsigned int offset, u32 mask, u32 val)
|
|
||||||
{
|
|
||||||
return mc13xxx_reg_rmw(mc13783_to_mc13xxx(mc13783), offset, mask, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_get_flags(struct mc13783 *mc13783)
|
|
||||||
{
|
|
||||||
return mc13xxx_get_flags(mc13783_to_mc13xxx(mc13783));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_request(struct mc13783 *mc13783, int irq,
|
|
||||||
irq_handler_t handler, const char *name, void *dev)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_request(mc13783_to_mc13xxx(mc13783), irq,
|
|
||||||
handler, name, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
|
|
||||||
irq_handler_t handler, const char *name, void *dev)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_request_nounmask(mc13783_to_mc13xxx(mc13783), irq,
|
|
||||||
handler, name, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_free(mc13783_to_mc13xxx(mc13783), irq, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_mask(mc13783_to_mc13xxx(mc13783), irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_unmask(mc13783_to_mc13xxx(mc13783), irq);
|
|
||||||
}
|
|
||||||
static inline int mc13783_irq_status(struct mc13783 *mc13783, int irq,
|
|
||||||
int *enabled, int *pending)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_status(mc13783_to_mc13xxx(mc13783),
|
|
||||||
irq, enabled, pending);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
|
|
||||||
{
|
|
||||||
return mc13xxx_irq_ack(mc13783_to_mc13xxx(mc13783), irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MC13783_ADC0 43
|
|
||||||
#define MC13783_ADC0_ADREFEN (1 << 10)
|
|
||||||
#define MC13783_ADC0_ADREFMODE (1 << 11)
|
|
||||||
#define MC13783_ADC0_TSMOD0 (1 << 12)
|
|
||||||
#define MC13783_ADC0_TSMOD1 (1 << 13)
|
|
||||||
#define MC13783_ADC0_TSMOD2 (1 << 14)
|
|
||||||
#define MC13783_ADC0_ADINC1 (1 << 16)
|
|
||||||
#define MC13783_ADC0_ADINC2 (1 << 17)
|
|
||||||
|
|
||||||
#define MC13783_ADC0_TSMOD_MASK (MC13783_ADC0_TSMOD0 | \
|
|
||||||
MC13783_ADC0_TSMOD1 | \
|
|
||||||
MC13783_ADC0_TSMOD2)
|
|
||||||
|
|
||||||
#define mc13783_regulator_init_data mc13xxx_regulator_init_data
|
|
||||||
#define mc13783_regulator_platform_data mc13xxx_regulator_platform_data
|
|
||||||
#define mc13783_led_platform_data mc13xxx_led_platform_data
|
|
||||||
#define mc13783_leds_platform_data mc13xxx_leds_platform_data
|
|
||||||
|
|
||||||
#define mc13783_platform_data mc13xxx_platform_data
|
|
||||||
#define MC13783_USE_TOUCHSCREEN MC13XXX_USE_TOUCHSCREEN
|
|
||||||
#define MC13783_USE_CODEC MC13XXX_USE_CODEC
|
|
||||||
#define MC13783_USE_ADC MC13XXX_USE_ADC
|
|
||||||
#define MC13783_USE_RTC MC13XXX_USE_RTC
|
|
||||||
#define MC13783_USE_REGULATOR MC13XXX_USE_REGULATOR
|
|
||||||
#define MC13783_USE_LED MC13XXX_USE_LED
|
|
||||||
|
|
||||||
#define MC13783_ADC_MODE_TS 1
|
|
||||||
#define MC13783_ADC_MODE_SINGLE_CHAN 2
|
|
||||||
#define MC13783_ADC_MODE_MULT_CHAN 3
|
|
||||||
|
|
||||||
int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
|
|
||||||
unsigned int channel, unsigned int *sample);
|
|
||||||
|
|
||||||
|
|
||||||
#define MC13783_REG_SW1A 0
|
#define MC13783_REG_SW1A 0
|
||||||
#define MC13783_REG_SW1B 1
|
#define MC13783_REG_SW1B 1
|
||||||
#define MC13783_REG_SW2A 2
|
#define MC13783_REG_SW2A 2
|
||||||
|
|
|
@ -37,6 +37,9 @@ int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
|
||||||
|
|
||||||
int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
|
int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
|
||||||
|
|
||||||
|
int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
|
||||||
|
unsigned int mode, unsigned int channel, unsigned int *sample);
|
||||||
|
|
||||||
#define MC13XXX_IRQ_ADCDONE 0
|
#define MC13XXX_IRQ_ADCDONE 0
|
||||||
#define MC13XXX_IRQ_ADCBISDONE 1
|
#define MC13XXX_IRQ_ADCBISDONE 1
|
||||||
#define MC13XXX_IRQ_TS 2
|
#define MC13XXX_IRQ_TS 2
|
||||||
|
@ -137,17 +140,48 @@ struct mc13xxx_leds_platform_data {
|
||||||
char tc3_period;
|
char tc3_period;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mc13xxx_buttons_platform_data {
|
||||||
|
#define MC13783_BUTTON_DBNC_0MS 0
|
||||||
|
#define MC13783_BUTTON_DBNC_30MS 1
|
||||||
|
#define MC13783_BUTTON_DBNC_150MS 2
|
||||||
|
#define MC13783_BUTTON_DBNC_750MS 3
|
||||||
|
#define MC13783_BUTTON_ENABLE (1 << 2)
|
||||||
|
#define MC13783_BUTTON_POL_INVERT (1 << 3)
|
||||||
|
#define MC13783_BUTTON_RESET_EN (1 << 4)
|
||||||
|
int b1on_flags;
|
||||||
|
unsigned short b1on_key;
|
||||||
|
int b2on_flags;
|
||||||
|
unsigned short b2on_key;
|
||||||
|
int b3on_flags;
|
||||||
|
unsigned short b3on_key;
|
||||||
|
};
|
||||||
|
|
||||||
struct mc13xxx_platform_data {
|
struct mc13xxx_platform_data {
|
||||||
#define MC13XXX_USE_TOUCHSCREEN (1 << 0)
|
#define MC13XXX_USE_TOUCHSCREEN (1 << 0)
|
||||||
#define MC13XXX_USE_CODEC (1 << 1)
|
#define MC13XXX_USE_CODEC (1 << 1)
|
||||||
#define MC13XXX_USE_ADC (1 << 2)
|
#define MC13XXX_USE_ADC (1 << 2)
|
||||||
#define MC13XXX_USE_RTC (1 << 3)
|
#define MC13XXX_USE_RTC (1 << 3)
|
||||||
#define MC13XXX_USE_REGULATOR (1 << 4)
|
|
||||||
#define MC13XXX_USE_LED (1 << 5)
|
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
struct mc13xxx_regulator_platform_data regulators;
|
struct mc13xxx_regulator_platform_data regulators;
|
||||||
struct mc13xxx_leds_platform_data *leds;
|
struct mc13xxx_leds_platform_data *leds;
|
||||||
|
struct mc13xxx_buttons_platform_data *buttons;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MC13XXX_ADC_MODE_TS 1
|
||||||
|
#define MC13XXX_ADC_MODE_SINGLE_CHAN 2
|
||||||
|
#define MC13XXX_ADC_MODE_MULT_CHAN 3
|
||||||
|
|
||||||
|
#define MC13XXX_ADC0 43
|
||||||
|
#define MC13XXX_ADC0_ADREFEN (1 << 10)
|
||||||
|
#define MC13XXX_ADC0_TSMOD0 (1 << 12)
|
||||||
|
#define MC13XXX_ADC0_TSMOD1 (1 << 13)
|
||||||
|
#define MC13XXX_ADC0_TSMOD2 (1 << 14)
|
||||||
|
#define MC13XXX_ADC0_ADINC1 (1 << 16)
|
||||||
|
#define MC13XXX_ADC0_ADINC2 (1 << 17)
|
||||||
|
|
||||||
|
#define MC13XXX_ADC0_TSMOD_MASK (MC13XXX_ADC0_TSMOD0 | \
|
||||||
|
MC13XXX_ADC0_TSMOD1 | \
|
||||||
|
MC13XXX_ADC0_TSMOD2)
|
||||||
|
|
||||||
#endif /* ifndef __LINUX_MFD_MC13XXX_H */
|
#endif /* ifndef __LINUX_MFD_MC13XXX_H */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/mfd/pcf50633/backlight.h>
|
#include <linux/mfd/pcf50633/backlight.h>
|
||||||
|
|
||||||
struct pcf50633;
|
struct pcf50633;
|
||||||
|
struct regmap;
|
||||||
|
|
||||||
#define PCF50633_NUM_REGULATORS 11
|
#define PCF50633_NUM_REGULATORS 11
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ enum {
|
||||||
|
|
||||||
struct pcf50633 {
|
struct pcf50633 {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct i2c_client *i2c_client;
|
struct regmap *regmap;
|
||||||
|
|
||||||
struct pcf50633_platform_data *pdata;
|
struct pcf50633_platform_data *pdata;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
|
@ -382,6 +382,7 @@ struct wm831x {
|
||||||
|
|
||||||
/* Used by the interrupt controller code to post writes */
|
/* Used by the interrupt controller code to post writes */
|
||||||
int gpio_update[WM831X_NUM_GPIO_REGS];
|
int gpio_update[WM831X_NUM_GPIO_REGS];
|
||||||
|
bool gpio_level[WM831X_NUM_GPIO_REGS];
|
||||||
|
|
||||||
struct mutex auxadc_lock;
|
struct mutex auxadc_lock;
|
||||||
struct list_head auxadc_pending;
|
struct list_head auxadc_pending;
|
||||||
|
|
|
@ -59,6 +59,8 @@ struct wm8994 {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
|
bool ldo_ena_always_driven;
|
||||||
|
|
||||||
int gpio_base;
|
int gpio_base;
|
||||||
int irq_base;
|
int irq_base;
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,13 @@ struct wm8994_pdata {
|
||||||
|
|
||||||
/* WM8958 microphone bias configuration */
|
/* WM8958 microphone bias configuration */
|
||||||
int micbias[2];
|
int micbias[2];
|
||||||
|
|
||||||
|
/* Disable the internal pull downs on the LDOs if they are
|
||||||
|
* always driven (eg, connected to an always on supply or
|
||||||
|
* GPIO that always drives an output. If they float power
|
||||||
|
* consumption will rise.
|
||||||
|
*/
|
||||||
|
bool ldo_ena_always_driven;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue