diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/mfd')
123 files changed, 0 insertions, 59623 deletions
diff --git a/ANDROID_3.4.5/drivers/mfd/88pm860x-core.c b/ANDROID_3.4.5/drivers/mfd/88pm860x-core.c deleted file mode 100644 index 87bd5ba3..00000000 --- a/ANDROID_3.4.5/drivers/mfd/88pm860x-core.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Base driver for Marvell 88PM8607 - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/mfd/core.h> -#include <linux/mfd/88pm860x.h> -#include <linux/regulator/machine.h> - -#define INT_STATUS_NUM 3 - -static struct resource bk_resources[] __devinitdata = { - {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,}, - {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,}, - {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,}, -}; - -static struct resource led_resources[] __devinitdata = { - {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,}, - {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,}, - {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO,}, - {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO,}, - {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,}, - {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,}, -}; - -static struct resource regulator_resources[] __devinitdata = { - {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,}, - {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,}, - {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,}, - {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,}, - {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,}, - {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,}, - {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,}, - {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,}, - {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,}, - {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,}, - {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,}, - {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,}, - {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,}, - {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,}, - {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,}, - {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,}, - {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,}, - {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,}, -}; - -static struct resource touch_resources[] __devinitdata = { - {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,}, -}; - -static struct resource onkey_resources[] __devinitdata = { - {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,}, -}; - -static struct resource codec_resources[] __devinitdata = { - /* Headset microphone insertion or removal */ - {PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,}, - /* Hook-switch press or release */ - {PM8607_IRQ_HOOK, PM8607_IRQ_HOOK, "hook", IORESOURCE_IRQ,}, - /* Headset insertion or removal */ - {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,}, - /* Audio short */ - {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,}, -}; - -static struct resource battery_resources[] __devinitdata = { - {PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,}, - {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,}, -}; - -static struct resource charger_resources[] __devinitdata = { - {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,}, - {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,}, - {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,}, - {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,}, - {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,}, - {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, -}; - -static struct resource rtc_resources[] __devinitdata = { - {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,}, -}; - -static struct mfd_cell bk_devs[] = { - {"88pm860x-backlight", 0,}, - {"88pm860x-backlight", 1,}, - {"88pm860x-backlight", 2,}, -}; - -static struct mfd_cell led_devs[] = { - {"88pm860x-led", 0,}, - {"88pm860x-led", 1,}, - {"88pm860x-led", 2,}, - {"88pm860x-led", 3,}, - {"88pm860x-led", 4,}, - {"88pm860x-led", 5,}, -}; - -static struct mfd_cell regulator_devs[] = { - {"88pm860x-regulator", 0,}, - {"88pm860x-regulator", 1,}, - {"88pm860x-regulator", 2,}, - {"88pm860x-regulator", 3,}, - {"88pm860x-regulator", 4,}, - {"88pm860x-regulator", 5,}, - {"88pm860x-regulator", 6,}, - {"88pm860x-regulator", 7,}, - {"88pm860x-regulator", 8,}, - {"88pm860x-regulator", 9,}, - {"88pm860x-regulator", 10,}, - {"88pm860x-regulator", 11,}, - {"88pm860x-regulator", 12,}, - {"88pm860x-regulator", 13,}, - {"88pm860x-regulator", 14,}, - {"88pm860x-regulator", 15,}, - {"88pm860x-regulator", 16,}, - {"88pm860x-regulator", 17,}, -}; - -static struct mfd_cell touch_devs[] = { - {"88pm860x-touch", -1,}, -}; - -static struct mfd_cell onkey_devs[] = { - {"88pm860x-onkey", -1,}, -}; - -static struct mfd_cell codec_devs[] = { - {"88pm860x-codec", -1,}, -}; - -static struct mfd_cell power_devs[] = { - {"88pm860x-battery", -1,}, - {"88pm860x-charger", -1,}, -}; - -static struct mfd_cell rtc_devs[] = { - {"88pm860x-rtc", -1,}, -}; - - -struct pm860x_irq_data { - int reg; - int mask_reg; - int enable; /* enable or not */ - int offs; /* bit offset in mask register */ -}; - -static struct pm860x_irq_data pm860x_irqs[] = { - [PM8607_IRQ_ONKEY] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 0, - }, - [PM8607_IRQ_EXTON] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 1, - }, - [PM8607_IRQ_CHG] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 2, - }, - [PM8607_IRQ_BAT] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 3, - }, - [PM8607_IRQ_RTC] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 4, - }, - [PM8607_IRQ_CC] = { - .reg = PM8607_INT_STATUS1, - .mask_reg = PM8607_INT_MASK_1, - .offs = 1 << 5, - }, - [PM8607_IRQ_VBAT] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 0, - }, - [PM8607_IRQ_VCHG] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 1, - }, - [PM8607_IRQ_VSYS] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 2, - }, - [PM8607_IRQ_TINT] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 3, - }, - [PM8607_IRQ_GPADC0] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 4, - }, - [PM8607_IRQ_GPADC1] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 5, - }, - [PM8607_IRQ_GPADC2] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 6, - }, - [PM8607_IRQ_GPADC3] = { - .reg = PM8607_INT_STATUS2, - .mask_reg = PM8607_INT_MASK_2, - .offs = 1 << 7, - }, - [PM8607_IRQ_AUDIO_SHORT] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 0, - }, - [PM8607_IRQ_PEN] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 1, - }, - [PM8607_IRQ_HEADSET] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 2, - }, - [PM8607_IRQ_HOOK] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 3, - }, - [PM8607_IRQ_MICIN] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 4, - }, - [PM8607_IRQ_CHG_FAIL] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 5, - }, - [PM8607_IRQ_CHG_DONE] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 6, - }, - [PM8607_IRQ_CHG_FAULT] = { - .reg = PM8607_INT_STATUS3, - .mask_reg = PM8607_INT_MASK_3, - .offs = 1 << 7, - }, -}; - -static irqreturn_t pm860x_irq(int irq, void *data) -{ - struct pm860x_chip *chip = data; - struct pm860x_irq_data *irq_data; - struct i2c_client *i2c; - int read_reg = -1, value = 0; - int i; - - i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; - for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { - irq_data = &pm860x_irqs[i]; - if (read_reg != irq_data->reg) { - read_reg = irq_data->reg; - value = pm860x_reg_read(i2c, irq_data->reg); - } - if (value & irq_data->enable) - handle_nested_irq(chip->irq_base + i); - } - return IRQ_HANDLED; -} - -static void pm860x_irq_lock(struct irq_data *data) -{ - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - - mutex_lock(&chip->irq_lock); -} - -static void pm860x_irq_sync_unlock(struct irq_data *data) -{ - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - struct pm860x_irq_data *irq_data; - struct i2c_client *i2c; - static unsigned char cached[3] = {0x0, 0x0, 0x0}; - unsigned char mask[3]; - int i; - - i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; - /* Load cached value. In initial, all IRQs are masked */ - for (i = 0; i < 3; i++) - mask[i] = cached[i]; - for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { - irq_data = &pm860x_irqs[i]; - switch (irq_data->mask_reg) { - case PM8607_INT_MASK_1: - mask[0] &= ~irq_data->offs; - mask[0] |= irq_data->enable; - break; - case PM8607_INT_MASK_2: - mask[1] &= ~irq_data->offs; - mask[1] |= irq_data->enable; - break; - case PM8607_INT_MASK_3: - mask[2] &= ~irq_data->offs; - mask[2] |= irq_data->enable; - break; - default: - dev_err(chip->dev, "wrong IRQ\n"); - break; - } - } - /* update mask into registers */ - for (i = 0; i < 3; i++) { - if (mask[i] != cached[i]) { - cached[i] = mask[i]; - pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]); - } - } - - mutex_unlock(&chip->irq_lock); -} - -static void pm860x_irq_enable(struct irq_data *data) -{ - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - pm860x_irqs[data->irq - chip->irq_base].enable - = pm860x_irqs[data->irq - chip->irq_base].offs; -} - -static void pm860x_irq_disable(struct irq_data *data) -{ - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - pm860x_irqs[data->irq - chip->irq_base].enable = 0; -} - -static struct irq_chip pm860x_irq_chip = { - .name = "88pm860x", - .irq_bus_lock = pm860x_irq_lock, - .irq_bus_sync_unlock = pm860x_irq_sync_unlock, - .irq_enable = pm860x_irq_enable, - .irq_disable = pm860x_irq_disable, -}; - -static int __devinit device_gpadc_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ - : chip->companion; - int data; - int ret; - - /* initialize GPADC without activating it */ - - if (!pdata || !pdata->touch) - return -EINVAL; - - /* set GPADC MISC1 register */ - data = 0; - data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK; - data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK; - data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK; - data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK; - if (data) { - ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data); - if (ret < 0) - goto out; - } - /* set tsi prebias time */ - if (pdata->touch->tsi_prebias) { - data = pdata->touch->tsi_prebias; - ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data); - if (ret < 0) - goto out; - } - /* set prebias & prechg time of pen detect */ - data = 0; - data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK; - data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK; - if (data) { - ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data); - if (ret < 0) - goto out; - } - - ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, - PM8607_GPADC_EN, PM8607_GPADC_EN); -out: - return ret; -} - -static int __devinit device_irq_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ - : chip->companion; - unsigned char status_buf[INT_STATUS_NUM]; - unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; - int i, data, mask, ret = -EINVAL; - int __irq; - - if (!pdata || !pdata->irq_base) { - dev_warn(chip->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } - - mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR - | PM8607_B0_MISC1_INT_MASK; - data = 0; - chip->irq_mode = 0; - if (pdata && pdata->irq_mode) { - /* - * irq_mode defines the way of clearing interrupt. If it's 1, - * clear IRQ by write. Otherwise, clear it by read. - * This control bit is valid from 88PM8607 B0 steping. - */ - data |= PM8607_B0_MISC1_INT_CLEAR; - chip->irq_mode = 1; - } - ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data); - if (ret < 0) - goto out; - - /* mask all IRQs */ - memset(status_buf, 0, INT_STATUS_NUM); - ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1, - INT_STATUS_NUM, status_buf); - if (ret < 0) - goto out; - - if (chip->irq_mode) { - /* clear interrupt status by write */ - memset(status_buf, 0xFF, INT_STATUS_NUM); - ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1, - INT_STATUS_NUM, status_buf); - } else { - /* clear interrupt status by read */ - ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1, - INT_STATUS_NUM, status_buf); - } - if (ret < 0) - goto out; - - mutex_init(&chip->irq_lock); - chip->irq_base = pdata->irq_base; - chip->core_irq = i2c->irq; - if (!chip->core_irq) - goto out; - - /* register IRQ by genirq */ - for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { - __irq = i + chip->irq_base; - irq_set_chip_data(__irq, chip); - irq_set_chip_and_handler(__irq, &pm860x_irq_chip, - handle_edge_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#else - irq_set_noprobe(__irq); -#endif - } - - ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags, - "88pm860x", chip); - if (ret) { - dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); - chip->core_irq = 0; - } - - return 0; -out: - chip->core_irq = 0; - return ret; -} - -static void device_irq_exit(struct pm860x_chip *chip) -{ - if (chip->core_irq) - free_irq(chip->core_irq, chip); -} - -int pm8606_osc_enable(struct pm860x_chip *chip, unsigned short client) -{ - int ret = -EIO; - struct i2c_client *i2c = (chip->id == CHIP_PM8606) ? - chip->client : chip->companion; - - dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client); - dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n", - __func__, chip->osc_vote, - chip->osc_status); - - mutex_lock(&chip->osc_lock); - /* Update voting status */ - chip->osc_vote |= client; - /* If reference group is off - turn on*/ - if (chip->osc_status != PM8606_REF_GP_OSC_ON) { - chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN; - /* Enable Reference group Vsys */ - if (pm860x_set_bits(i2c, PM8606_VSYS, - PM8606_VSYS_EN, PM8606_VSYS_EN)) - goto out; - - /*Enable Internal Oscillator */ - if (pm860x_set_bits(i2c, PM8606_MISC, - PM8606_MISC_OSC_EN, PM8606_MISC_OSC_EN)) - goto out; - /* Update status (only if writes succeed) */ - chip->osc_status = PM8606_REF_GP_OSC_ON; - } - mutex_unlock(&chip->osc_lock); - - dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n", - __func__, chip->osc_vote, - chip->osc_status, ret); - return 0; -out: - mutex_unlock(&chip->osc_lock); - return ret; -} -EXPORT_SYMBOL(pm8606_osc_enable); - -int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client) -{ - int ret = -EIO; - struct i2c_client *i2c = (chip->id == CHIP_PM8606) ? - chip->client : chip->companion; - - dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client); - dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n", - __func__, chip->osc_vote, - chip->osc_status); - - mutex_lock(&chip->osc_lock); - /*Update voting status */ - chip->osc_vote &= ~(client); - /* If reference group is off and this is the last client to release - * - turn off */ - if ((chip->osc_status != PM8606_REF_GP_OSC_OFF) && - (chip->osc_vote == REF_GP_NO_CLIENTS)) { - chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN; - /* Disable Reference group Vsys */ - if (pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0)) - goto out; - /* Disable Internal Oscillator */ - if (pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0)) - goto out; - chip->osc_status = PM8606_REF_GP_OSC_OFF; - } - mutex_unlock(&chip->osc_lock); - - dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n", - __func__, chip->osc_vote, - chip->osc_status, ret); - return 0; -out: - mutex_unlock(&chip->osc_lock); - return ret; -} -EXPORT_SYMBOL(pm8606_osc_disable); - -static void __devinit device_osc_init(struct i2c_client *i2c) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - - mutex_init(&chip->osc_lock); - /* init portofino reference group voting and status */ - /* Disable Reference group Vsys */ - pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0); - /* Disable Internal Oscillator */ - pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0); - - chip->osc_vote = REF_GP_NO_CLIENTS; - chip->osc_status = PM8606_REF_GP_OSC_OFF; -} - -static void __devinit device_bk_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - int i, j, id; - - if ((pdata == NULL) || (pdata->backlight == NULL)) - return; - - if (pdata->num_backlights > ARRAY_SIZE(bk_devs)) - pdata->num_backlights = ARRAY_SIZE(bk_devs); - - for (i = 0; i < pdata->num_backlights; i++) { - bk_devs[i].platform_data = &pdata->backlight[i]; - bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata); - - for (j = 0; j < ARRAY_SIZE(bk_devs); j++) { - id = bk_resources[j].start; - if (pdata->backlight[i].flags != id) - continue; - - bk_devs[i].num_resources = 1; - bk_devs[i].resources = &bk_resources[j]; - ret = mfd_add_devices(chip->dev, 0, - &bk_devs[i], 1, - &bk_resources[j], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add " - "backlight subdev\n"); - return; - } - } - } -} - -static void __devinit device_led_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - int i, j, id; - - if ((pdata == NULL) || (pdata->led == NULL)) - return; - - if (pdata->num_leds > ARRAY_SIZE(led_devs)) - pdata->num_leds = ARRAY_SIZE(led_devs); - - for (i = 0; i < pdata->num_leds; i++) { - led_devs[i].platform_data = &pdata->led[i]; - led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata); - - for (j = 0; j < ARRAY_SIZE(led_devs); j++) { - id = led_resources[j].start; - if (pdata->led[i].flags != id) - continue; - - led_devs[i].num_resources = 1; - led_devs[i].resources = &led_resources[j], - ret = mfd_add_devices(chip->dev, 0, - &led_devs[i], 1, - &led_resources[j], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add " - "led subdev\n"); - return; - } - } - } -} - -static void __devinit device_regulator_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - struct regulator_init_data *initdata; - int ret; - int i, seq; - - if ((pdata == NULL) || (pdata->regulator == NULL)) - return; - - if (pdata->num_regulators > ARRAY_SIZE(regulator_devs)) - pdata->num_regulators = ARRAY_SIZE(regulator_devs); - - for (i = 0, seq = -1; i < pdata->num_regulators; i++) { - initdata = &pdata->regulator[i]; - seq = *(unsigned int *)initdata->driver_data; - if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) { - dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n", - seq, initdata->constraints.name); - goto out; - } - regulator_devs[i].platform_data = &pdata->regulator[i]; - regulator_devs[i].pdata_size = sizeof(struct regulator_init_data); - regulator_devs[i].num_resources = 1; - regulator_devs[i].resources = ®ulator_resources[seq]; - - ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, - ®ulator_resources[seq], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add regulator subdev\n"); - goto out; - } - } -out: - return; -} - -static void __devinit device_rtc_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - - if ((pdata == NULL)) - return; - - rtc_devs[0].platform_data = pdata->rtc; - rtc_devs[0].pdata_size = sizeof(struct pm860x_rtc_pdata); - rtc_devs[0].num_resources = ARRAY_SIZE(rtc_resources); - rtc_devs[0].resources = &rtc_resources[0]; - ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], - ARRAY_SIZE(rtc_devs), &rtc_resources[0], - chip->irq_base); - if (ret < 0) - dev_err(chip->dev, "Failed to add rtc subdev\n"); -} - -static void __devinit device_touch_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - - if (pdata == NULL) - return; - - touch_devs[0].platform_data = pdata->touch; - touch_devs[0].pdata_size = sizeof(struct pm860x_touch_pdata); - touch_devs[0].num_resources = ARRAY_SIZE(touch_resources); - touch_devs[0].resources = &touch_resources[0]; - ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], - ARRAY_SIZE(touch_devs), &touch_resources[0], - chip->irq_base); - if (ret < 0) - dev_err(chip->dev, "Failed to add touch subdev\n"); -} - -static void __devinit device_power_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - - if (pdata == NULL) - return; - - power_devs[0].platform_data = pdata->power; - power_devs[0].pdata_size = sizeof(struct pm860x_power_pdata); - power_devs[0].num_resources = ARRAY_SIZE(battery_resources); - power_devs[0].resources = &battery_resources[0], - ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, - &battery_resources[0], chip->irq_base); - if (ret < 0) - dev_err(chip->dev, "Failed to add battery subdev\n"); - - power_devs[1].platform_data = pdata->power; - power_devs[1].pdata_size = sizeof(struct pm860x_power_pdata); - power_devs[1].num_resources = ARRAY_SIZE(charger_resources); - power_devs[1].resources = &charger_resources[0], - ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, - &charger_resources[0], chip->irq_base); - if (ret < 0) - dev_err(chip->dev, "Failed to add charger subdev\n"); -} - -static void __devinit device_onkey_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - - onkey_devs[0].num_resources = ARRAY_SIZE(onkey_resources); - onkey_devs[0].resources = &onkey_resources[0], - ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], - ARRAY_SIZE(onkey_devs), &onkey_resources[0], - chip->irq_base); - if (ret < 0) - dev_err(chip->dev, "Failed to add onkey subdev\n"); -} - -static void __devinit device_codec_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - int ret; - - codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); - codec_devs[0].resources = &codec_resources[0], - ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], - ARRAY_SIZE(codec_devs), &codec_resources[0], 0); - if (ret < 0) - dev_err(chip->dev, "Failed to add codec subdev\n"); -} - -static void __devinit device_8607_init(struct pm860x_chip *chip, - struct i2c_client *i2c, - struct pm860x_platform_data *pdata) -{ - int data, ret; - - ret = pm860x_reg_read(i2c, PM8607_CHIP_ID); - if (ret < 0) { - dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret); - goto out; - } - switch (ret & PM8607_VERSION_MASK) { - case 0x40: - case 0x50: - dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n", - ret); - break; - default: - dev_err(chip->dev, "Failed to detect Marvell 88PM8607. " - "Chip ID: %02x\n", ret); - goto out; - } - - ret = pm860x_reg_read(i2c, PM8607_BUCK3); - if (ret < 0) { - dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret); - goto out; - } - if (ret & PM8607_BUCK3_DOUBLE) - chip->buck3_double = 1; - - ret = pm860x_reg_read(i2c, PM8607_B0_MISC1); - if (ret < 0) { - dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret); - goto out; - } - - if (pdata && (pdata->i2c_port == PI2C_PORT)) - data = PM8607_B0_MISC1_PI2C; - else - data = 0; - ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data); - if (ret < 0) { - dev_err(chip->dev, "Failed to access MISC1:%d\n", ret); - goto out; - } - - ret = device_gpadc_init(chip, pdata); - if (ret < 0) - goto out; - - ret = device_irq_init(chip, pdata); - if (ret < 0) - goto out; - - device_regulator_init(chip, pdata); - device_rtc_init(chip, pdata); - device_onkey_init(chip, pdata); - device_touch_init(chip, pdata); - device_power_init(chip, pdata); - device_codec_init(chip, pdata); -out: - return; -} - -static void __devinit device_8606_init(struct pm860x_chip *chip, - struct i2c_client *i2c, - struct pm860x_platform_data *pdata) -{ - device_osc_init(i2c); - device_bk_init(chip, pdata); - device_led_init(chip, pdata); -} - -int __devinit pm860x_device_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata) -{ - chip->core_irq = 0; - - switch (chip->id) { - case CHIP_PM8606: - device_8606_init(chip, chip->client, pdata); - break; - case CHIP_PM8607: - device_8607_init(chip, chip->client, pdata); - break; - } - - if (chip->companion) { - switch (chip->id) { - case CHIP_PM8607: - device_8606_init(chip, chip->companion, pdata); - break; - case CHIP_PM8606: - device_8607_init(chip, chip->companion, pdata); - break; - } - } - - return 0; -} - -void __devexit pm860x_device_exit(struct pm860x_chip *chip) -{ - device_irq_exit(chip); - mfd_remove_devices(chip->dev); -} - -MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x"); -MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/88pm860x-i2c.c b/ANDROID_3.4.5/drivers/mfd/88pm860x-i2c.c deleted file mode 100644 index b2cfdc45..00000000 --- a/ANDROID_3.4.5/drivers/mfd/88pm860x-i2c.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * I2C driver for Marvell 88PM860x - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/err.h> -#include <linux/regmap.h> -#include <linux/mfd/88pm860x.h> -#include <linux/slab.h> - -int pm860x_reg_read(struct i2c_client *i2c, int reg) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - struct regmap *map = (i2c == chip->client) ? chip->regmap - : chip->regmap_companion; - unsigned int data; - int ret; - - ret = regmap_read(map, reg, &data); - if (ret < 0) - return ret; - else - return (int)data; -} -EXPORT_SYMBOL(pm860x_reg_read); - -int pm860x_reg_write(struct i2c_client *i2c, int reg, - unsigned char data) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - struct regmap *map = (i2c == chip->client) ? chip->regmap - : chip->regmap_companion; - int ret; - - ret = regmap_write(map, reg, data); - return ret; -} -EXPORT_SYMBOL(pm860x_reg_write); - -int pm860x_bulk_read(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - struct regmap *map = (i2c == chip->client) ? chip->regmap - : chip->regmap_companion; - int ret; - - ret = regmap_raw_read(map, reg, buf, count); - return ret; -} -EXPORT_SYMBOL(pm860x_bulk_read); - -int pm860x_bulk_write(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - struct regmap *map = (i2c == chip->client) ? chip->regmap - : chip->regmap_companion; - int ret; - - ret = regmap_raw_write(map, reg, buf, count); - return ret; -} -EXPORT_SYMBOL(pm860x_bulk_write); - -int pm860x_set_bits(struct i2c_client *i2c, int reg, - unsigned char mask, unsigned char data) -{ - struct pm860x_chip *chip = i2c_get_clientdata(i2c); - struct regmap *map = (i2c == chip->client) ? chip->regmap - : chip->regmap_companion; - int ret; - - ret = regmap_update_bits(map, reg, mask, data); - return ret; -} -EXPORT_SYMBOL(pm860x_set_bits); - -static int read_device(struct i2c_client *i2c, int reg, - int bytes, void *dest) -{ - unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3]; - unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2]; - struct i2c_adapter *adap = i2c->adapter; - struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0}, - {i2c->addr, I2C_M_RD, 0, msgbuf1}, - }; - int num = 1, ret = 0; - - if (dest == NULL) - return -EINVAL; - msgbuf0[0] = (unsigned char)reg; /* command */ - msg[1].len = bytes; - - /* if data needs to read back, num should be 2 */ - if (bytes > 0) - num = 2; - ret = adap->algo->master_xfer(adap, msg, num); - memcpy(dest, msgbuf1, bytes); - if (ret < 0) - return ret; - return 0; -} - -static int write_device(struct i2c_client *i2c, int reg, - int bytes, void *src) -{ - unsigned char buf[bytes + 1]; - struct i2c_adapter *adap = i2c->adapter; - struct i2c_msg msg; - int ret; - - buf[0] = (unsigned char)reg; - memcpy(&buf[1], src, bytes); - msg.addr = i2c->addr; - msg.flags = 0; - msg.len = bytes + 1; - msg.buf = buf; - - ret = adap->algo->master_xfer(adap, &msg, 1); - if (ret < 0) - return ret; - return 0; -} - -int pm860x_page_reg_read(struct i2c_client *i2c, int reg) -{ - unsigned char zero = 0; - unsigned char data; - int ret; - - i2c_lock_adapter(i2c->adapter); - read_device(i2c, 0xFA, 0, &zero); - read_device(i2c, 0xFB, 0, &zero); - read_device(i2c, 0xFF, 0, &zero); - ret = read_device(i2c, reg, 1, &data); - if (ret >= 0) - ret = (int)data; - read_device(i2c, 0xFE, 0, &zero); - read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); - return ret; -} -EXPORT_SYMBOL(pm860x_page_reg_read); - -int pm860x_page_reg_write(struct i2c_client *i2c, int reg, - unsigned char data) -{ - unsigned char zero; - int ret; - - i2c_lock_adapter(i2c->adapter); - read_device(i2c, 0xFA, 0, &zero); - read_device(i2c, 0xFB, 0, &zero); - read_device(i2c, 0xFF, 0, &zero); - ret = write_device(i2c, reg, 1, &data); - read_device(i2c, 0xFE, 0, &zero); - read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); - return ret; -} -EXPORT_SYMBOL(pm860x_page_reg_write); - -int pm860x_page_bulk_read(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - unsigned char zero = 0; - int ret; - - i2c_lock_adapter(i2c->adapter); - read_device(i2c, 0xfa, 0, &zero); - read_device(i2c, 0xfb, 0, &zero); - read_device(i2c, 0xff, 0, &zero); - ret = read_device(i2c, reg, count, buf); - read_device(i2c, 0xFE, 0, &zero); - read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); - return ret; -} -EXPORT_SYMBOL(pm860x_page_bulk_read); - -int pm860x_page_bulk_write(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - unsigned char zero = 0; - int ret; - - i2c_lock_adapter(i2c->adapter); - read_device(i2c, 0xFA, 0, &zero); - read_device(i2c, 0xFB, 0, &zero); - read_device(i2c, 0xFF, 0, &zero); - ret = write_device(i2c, reg, count, buf); - read_device(i2c, 0xFE, 0, &zero); - read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); - i2c_unlock_adapter(i2c->adapter); - return ret; -} -EXPORT_SYMBOL(pm860x_page_bulk_write); - -int pm860x_page_set_bits(struct i2c_client *i2c, int reg, - unsigned char mask, unsigned char data) -{ - unsigned char zero; - unsigned char value; - int ret; - - i2c_lock_adapter(i2c->adapter); - read_device(i2c, 0xFA, 0, &zero); - read_device(i2c, 0xFB, 0, &zero); - read_device(i2c, 0xFF, 0, &zero); - ret = read_device(i2c, reg, 1, &value); - if (ret < 0) - goto out; - value &= ~mask; - value |= data; - ret = write_device(i2c, reg, 1, &value); -out: - read_device(i2c, 0xFE, 0, &zero); - read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); - return ret; -} -EXPORT_SYMBOL(pm860x_page_set_bits); - -static const struct i2c_device_id pm860x_id_table[] = { - { "88PM860x", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, pm860x_id_table); - -static int verify_addr(struct i2c_client *i2c) -{ - unsigned short addr_8607[] = {0x30, 0x34}; - unsigned short addr_8606[] = {0x10, 0x11}; - int size, i; - - if (i2c == NULL) - return 0; - size = ARRAY_SIZE(addr_8606); - for (i = 0; i < size; i++) { - if (i2c->addr == *(addr_8606 + i)) - return CHIP_PM8606; - } - size = ARRAY_SIZE(addr_8607); - for (i = 0; i < size; i++) { - if (i2c->addr == *(addr_8607 + i)) - return CHIP_PM8607; - } - return 0; -} - -static struct regmap_config pm860x_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -}; - -static int __devinit pm860x_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct pm860x_platform_data *pdata = client->dev.platform_data; - struct pm860x_chip *chip; - int ret; - - if (!pdata) { - pr_info("No platform data in %s!\n", __func__); - return -EINVAL; - } - - chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - - chip->id = verify_addr(client); - chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); - if (IS_ERR(chip->regmap)) { - ret = PTR_ERR(chip->regmap); - dev_err(&client->dev, "Failed to allocate register map: %d\n", - ret); - kfree(chip); - return ret; - } - chip->client = client; - i2c_set_clientdata(client, chip); - chip->dev = &client->dev; - dev_set_drvdata(chip->dev, chip); - - /* - * Both client and companion client shares same platform driver. - * Driver distinguishes them by pdata->companion_addr. - * pdata->companion_addr is only assigned if companion chip exists. - * At the same time, the companion_addr shouldn't equal to client - * address. - */ - if (pdata->companion_addr && (pdata->companion_addr != client->addr)) { - chip->companion_addr = pdata->companion_addr; - chip->companion = i2c_new_dummy(chip->client->adapter, - chip->companion_addr); - chip->regmap_companion = regmap_init_i2c(chip->companion, - &pm860x_regmap_config); - if (IS_ERR(chip->regmap_companion)) { - ret = PTR_ERR(chip->regmap_companion); - dev_err(&chip->companion->dev, - "Failed to allocate register map: %d\n", ret); - return ret; - } - i2c_set_clientdata(chip->companion, chip); - } - - pm860x_device_init(chip, pdata); - return 0; -} - -static int __devexit pm860x_remove(struct i2c_client *client) -{ - struct pm860x_chip *chip = i2c_get_clientdata(client); - - pm860x_device_exit(chip); - if (chip->companion) { - regmap_exit(chip->regmap_companion); - i2c_unregister_device(chip->companion); - } - regmap_exit(chip->regmap); - kfree(chip); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int pm860x_suspend(struct device *dev) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - struct pm860x_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev) && chip->wakeup_flag) - enable_irq_wake(chip->core_irq); - return 0; -} - -static int pm860x_resume(struct device *dev) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - struct pm860x_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev) && chip->wakeup_flag) - disable_irq_wake(chip->core_irq); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume); - -static struct i2c_driver pm860x_driver = { - .driver = { - .name = "88PM860x", - .owner = THIS_MODULE, - .pm = &pm860x_pm_ops, - }, - .probe = pm860x_probe, - .remove = __devexit_p(pm860x_remove), - .id_table = pm860x_id_table, -}; - -static int __init pm860x_i2c_init(void) -{ - int ret; - ret = i2c_add_driver(&pm860x_driver); - if (ret != 0) - pr_err("Failed to register 88PM860x I2C driver: %d\n", ret); - return ret; -} -subsys_initcall(pm860x_i2c_init); - -static void __exit pm860x_i2c_exit(void) -{ - i2c_del_driver(&pm860x_driver); -} -module_exit(pm860x_i2c_exit); - -MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x"); -MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/Kconfig b/ANDROID_3.4.5/drivers/mfd/Kconfig deleted file mode 100644 index ca4ab95a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/Kconfig +++ /dev/null @@ -1,936 +0,0 @@ -# -# Multifunction miscellaneous devices -# - -if HAS_IOMEM -menu "Multifunction device drivers" - -config MFD_CORE - tristate - default n - -config MFD_88PM860X - bool "Support Marvell 88PM8606/88PM8607" - depends on I2C=y && GENERIC_HARDIRQS - select REGMAP_I2C - select MFD_CORE - help - This supports for Marvell 88PM8606/88PM8607 Power Management IC. - This includes the I2C driver and the core APIs _only_, you have to - select individual components like voltage regulators, RTC and - battery-charger under the corresponding menus. - -config MFD_SM501 - tristate "Support for Silicon Motion SM501" - ---help--- - This is the core driver for the Silicon Motion SM501 multimedia - companion chip. This device is a multifunction device which may - provide numerous interfaces including USB host controller, USB gadget, - asynchronous serial ports, audio functions, and a dual display video - interface. The device may be connected by PCI or local bus with - varying functions enabled. - -config MFD_SM501_GPIO - bool "Export GPIO via GPIO layer" - depends on MFD_SM501 && GPIOLIB - ---help--- - This option uses the gpio library layer to export the 64 GPIO - lines on the SM501. The platform data is used to supply the - base number for the first GPIO line to register. - -config MFD_ASIC3 - bool "Support for Compaq ASIC3" - depends on GENERIC_HARDIRQS && GPIOLIB && ARM - select MFD_CORE - ---help--- - This driver supports the ASIC3 multifunction chip found on many - PDAs (mainly iPAQ and HTC based ones) - -config MFD_DAVINCI_VOICECODEC - tristate - select MFD_CORE - -config MFD_DM355EVM_MSP - bool "DaVinci DM355 EVM microcontroller" - depends on I2C=y && MACH_DAVINCI_DM355_EVM - help - This driver supports the MSP430 microcontroller used on these - boards. MSP430 firmware manages resets and power sequencing, - inputs from buttons and the IR remote, LEDs, an RTC, and more. - -config MFD_TI_SSP - tristate "TI Sequencer Serial Port support" - depends on ARCH_DAVINCI_TNETV107X - select MFD_CORE - ---help--- - Say Y here if you want support for the Sequencer Serial Port - in a Texas Instruments TNETV107X SoC. - - To compile this driver as a module, choose M here: the - module will be called ti-ssp. - -config HTC_EGPIO - bool "HTC EGPIO support" - depends on GENERIC_HARDIRQS && GPIOLIB && ARM - help - This driver supports the CPLD egpio chip present on - several HTC phones. It provides basic support for input - pins, output pins, and irqs. - -config HTC_PASIC3 - tristate "HTC PASIC3 LED/DS1WM chip support" - select MFD_CORE - help - This core driver provides register access for the LED/DS1WM - chips labeled "AIC2" and "AIC3", found on HTC Blueangel and - HTC Magician devices, respectively. Actual functionality is - handled by the leds-pasic3 and ds1wm drivers. - -config HTC_I2CPLD - bool "HTC I2C PLD chip support" - depends on I2C=y && GPIOLIB - help - If you say yes here you get support for the supposed CPLD - found on omap850 HTC devices like the HTC Wizard and HTC Herald. - This device provides input and output GPIOs through an I2C - interface to one or more sub-chips. - -config UCB1400_CORE - tristate "Philips UCB1400 Core driver" - depends on AC97_BUS - depends on GPIOLIB - help - This enables support for the Philips UCB1400 core functions. - The UCB1400 is an AC97 audio codec. - - To compile this driver as a module, choose M here: the - module will be called ucb1400_core. - -config TPS6105X - tristate "TPS61050/61052 Boost Converters" - depends on I2C - select REGULATOR - select MFD_CORE - select REGULATOR_FIXED_VOLTAGE - help - This option enables a driver for the TP61050/TPS61052 - high-power "white LED driver". This boost converter is - sometimes used for other things than white LEDs, and - also contains a GPIO pin. - -config TPS65010 - tristate "TPS6501x Power Management chips" - depends on I2C && GPIOLIB - default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK - help - If you say yes here you get support for the TPS6501x series of - Power Management chips. These include voltage regulators, - lithium ion/polymer battery charging, and other features that - are often used in portable devices like cell phones and cameras. - - This driver can also be built as a module. If so, the module - will be called tps65010. - -config TPS6507X - tristate "TPS6507x Power Management / Touch Screen chips" - select MFD_CORE - depends on I2C - help - If you say yes here you get support for the TPS6507x series of - Power Management / Touch Screen chips. These include voltage - regulators, lithium ion/polymer battery charging, touch screen - and other features that are often used in portable devices. - This driver can also be built as a module. If so, the module - will be called tps6507x. - -config MFD_TPS65217 - tristate "TPS65217 Power Management / White LED chips" - depends on I2C - select MFD_CORE - select REGMAP_I2C - help - If you say yes here you get support for the TPS65217 series of - Power Management / White LED chips. - These include voltage regulators, lithium ion/polymer battery - charger, wled and other features that are often used in portable - devices. - - This driver can also be built as a module. If so, the module - will be called tps65217. - -config MFD_TPS6586X - bool "TPS6586x Power Management chips" - depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS - select MFD_CORE - help - If you say yes here you get support for the TPS6586X series of - Power Management chips. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device. - - This driver can also be built as a module. If so, the module - will be called tps6586x. - -config MFD_TPS65910 - bool "TPS65910 Power Management chip" - depends on I2C=y && GPIOLIB - select MFD_CORE - select GPIO_TPS65910 - select REGMAP_I2C - help - if you say yes here you get support for the TPS65910 series of - Power Management chips. - -config MFD_TPS65912 - bool - depends on GPIOLIB - -config MFD_TPS65912_I2C - bool "TPS65912 Power Management chip with I2C" - select MFD_CORE - select MFD_TPS65912 - depends on I2C=y && GPIOLIB - help - If you say yes here you get support for the TPS65912 series of - PM chips with I2C interface. - -config MFD_TPS65912_SPI - bool "TPS65912 Power Management chip with SPI" - select MFD_CORE - select MFD_TPS65912 - depends on SPI_MASTER && GPIOLIB - help - If you say yes here you get support for the TPS65912 series of - PM chips with SPI interface. - -config MENELAUS - bool "Texas Instruments TWL92330/Menelaus PM chip" - depends on I2C=y && ARCH_OMAP2 - help - If you say yes here you get support for the Texas Instruments - TWL92330/Menelaus Power Management chip. This include voltage - regulators, Dual slot memory card transceivers, real-time clock - and other features that are often used in portable devices like - cell phones and PDAs. - -config TWL4030_CORE - bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" - depends on I2C=y && GENERIC_HARDIRQS - select IRQ_DOMAIN - help - Say yes here if you have TWL4030 / TWL6030 family chip on your board. - This core driver provides register access and IRQ handling - facilities, and registers devices for the various functions - so that function-specific drivers can bind to them. - - These multi-function chips are found on many OMAP2 and OMAP3 - boards, providing power management, RTC, GPIO, keypad, a - high speed USB OTG transceiver, an audio codec (on most - versions) and many other features. - -config TWL4030_MADC - tristate "Texas Instruments TWL4030 MADC" - depends on TWL4030_CORE - help - This driver provides support for triton TWL4030-MADC. The - driver supports both RT and SW conversion methods. - - This driver can be built as a module. If so it will be - named twl4030-madc - -config TWL4030_POWER - bool "Support power resources on TWL4030 family chips" - depends on TWL4030_CORE && ARM - help - Say yes here if you want to use the power resources on the - TWL4030 family chips. Most of these resources are regulators, - which have a separate driver; some are control signals, such - as clock request handshaking. - - This driver uses board-specific data to initialize the resources - and load scripts controlling which resources are switched off/on - or reset when a sleep, wakeup or warm reset event occurs. - -config MFD_TWL4030_AUDIO - bool - depends on TWL4030_CORE - select MFD_CORE - default n - -config TWL6030_PWM - tristate "TWL6030 PWM (Pulse Width Modulator) Support" - depends on TWL4030_CORE - select HAVE_PWM - default n - help - Say yes here if you want support for TWL6030 PWM. - This is used to control charging LED brightness. - -config TWL6040_CORE - bool "Support for TWL6040 audio codec" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - select REGMAP_I2C - default n - help - Say yes here if you want support for Texas Instruments TWL6040 audio - codec. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device (audio, vibra). - -config MFD_STMPE - bool "Support STMicroelectronics STMPE" - depends on (I2C=y || SPI_MASTER=y) && GENERIC_HARDIRQS - select MFD_CORE - help - Support for the STMPE family of I/O Expanders from - STMicroelectronics. - - Currently supported devices are: - - STMPE811: GPIO, Touchscreen - STMPE1601: GPIO, Keypad - STMPE2401: GPIO, Keypad - STMPE2403: GPIO, Keypad - - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the functionality - of the device. Currently available sub drivers are: - - GPIO: stmpe-gpio - Keypad: stmpe-keypad - Touchscreen: stmpe-ts - -menu "STMPE Interface Drivers" -depends on MFD_STMPE - -config STMPE_I2C - bool "STMPE I2C Inteface" - depends on I2C=y - default y - help - This is used to enable I2C interface of STMPE - -config STMPE_SPI - bool "STMPE SPI Inteface" - depends on SPI_MASTER - help - This is used to enable SPI interface of STMPE -endmenu - -config MFD_TC3589X - bool "Support Toshiba TC35892 and variants" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - help - Support for the Toshiba TC35892 and variants I/O Expander. - - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device. - -config MFD_TMIO - bool - default n - -config MFD_T7L66XB - bool "Support Toshiba T7L66XB" - depends on ARM && HAVE_CLK - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller T7L66XB - -config MFD_TC6387XB - bool "Support Toshiba TC6387XB" - depends on ARM && HAVE_CLK - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller TC6387XB - -config MFD_TC6393XB - bool "Support Toshiba TC6393XB" - depends on GPIOLIB && ARM && HAVE_CLK - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller TC6393XB - -config PMIC_DA903X - bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" - depends on I2C=y - help - Say yes here to support for Dialog Semiconductor DA9030 (a.k.a - ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC - usually found on PXA processors-based platforms. This includes - the I2C driver and the core APIs _only_, you have to select - individual components like LCD backlight, voltage regulators, - LEDs and battery-charger under the corresponding menus. - -config PMIC_DA9052 - bool - select MFD_CORE - -config MFD_DA9052_SPI - bool "Support Dialog Semiconductor DA9052/53 PMIC variants with SPI" - select REGMAP_SPI - select REGMAP_IRQ - select PMIC_DA9052 - depends on SPI_MASTER=y - help - Support for the Dialog Semiconductor DA9052 PMIC - when controlled using SPI. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - -config MFD_DA9052_I2C - bool "Support Dialog Semiconductor DA9052/53 PMIC variants with I2C" - select REGMAP_I2C - select REGMAP_IRQ - select PMIC_DA9052 - depends on I2C=y - help - Support for the Dialog Semiconductor DA9052 PMIC - when controlled using I2C. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - -config PMIC_ADP5520 - bool "Analog Devices ADP5520/01 MFD PMIC Core Support" - depends on I2C=y - help - Say yes here to add support for Analog Devices AD5520 and ADP5501, - Multifunction Power Management IC. This includes - the I2C driver and the core APIs _only_, you have to select - individual components like LCD backlight, LEDs, GPIOs and Kepad - under the corresponding menus. - -config MFD_MAX8925 - bool "Maxim Semiconductor MAX8925 PMIC Support" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - help - Say yes here to support for Maxim Semiconductor MAX8925. This is - a Power Management IC. This driver provies common support for - accessing the device, additional drivers must be enabled in order - to use the functionality of the device. - -config MFD_MAX8997 - bool "Maxim Semiconductor MAX8997/8966 PMIC Support" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - help - Say yes here to support for Maxim Semiconductor MAX8997/8966. - This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic, - MUIC controls on chip. - This driver provides common support for accessing the device; - additional drivers must be enabled in order to use the functionality - of the device. - -config MFD_MAX8998 - bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - help - Say yes here to support for Maxim Semiconductor MAX8998 and - National Semiconductor LP3974. This is a Power Management IC. - This driver provies common support for accessing the device, - additional drivers must be enabled in order to use the functionality - of the device. - -config MFD_S5M_CORE - bool "SAMSUNG S5M Series Support" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - select REGMAP_I2C - help - Support for the Samsung Electronics S5M MFD series. - This driver provies common support for accessing the device, - additional drivers must be enabled in order to use the functionality - of the device - -config MFD_WM8400 - tristate "Support Wolfson Microelectronics WM8400" - select MFD_CORE - depends on I2C - select REGMAP_I2C - help - Support for the Wolfson Microelecronics WM8400 PMIC and audio - CODEC. This driver provides common support for accessing - the device, additional drivers must be enabled in order to use - the functionality of the device. - -config MFD_WM831X - bool - depends on GENERIC_HARDIRQS - -config MFD_WM831X_I2C - bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C" - select MFD_CORE - select MFD_WM831X - select REGMAP_I2C - depends on I2C=y && GENERIC_HARDIRQS - help - Support for the Wolfson Microelecronics WM831x and WM832x PMICs - when controlled using I2C. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - -config MFD_WM831X_SPI - bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI" - select MFD_CORE - select MFD_WM831X - select REGMAP_SPI - depends on SPI_MASTER && GENERIC_HARDIRQS - help - Support for the Wolfson Microelecronics WM831x and WM832x PMICs - when controlled using SPI. This driver provides common support - for accessing the device, additional drivers must be enabled in - order to use the functionality of the device. - -config MFD_WM8350 - bool - depends on GENERIC_HARDIRQS - -config MFD_WM8350_CONFIG_MODE_0 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_1 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_2 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_3 - bool - depends on MFD_WM8350 - -config MFD_WM8351_CONFIG_MODE_0 - bool - depends on MFD_WM8350 - -config MFD_WM8351_CONFIG_MODE_1 - bool - depends on MFD_WM8350 - -config MFD_WM8351_CONFIG_MODE_2 - bool - depends on MFD_WM8350 - -config MFD_WM8351_CONFIG_MODE_3 - bool - depends on MFD_WM8350 - -config MFD_WM8352_CONFIG_MODE_0 - bool - depends on MFD_WM8350 - -config MFD_WM8352_CONFIG_MODE_1 - bool - depends on MFD_WM8350 - -config MFD_WM8352_CONFIG_MODE_2 - bool - depends on MFD_WM8350 - -config MFD_WM8352_CONFIG_MODE_3 - bool - depends on MFD_WM8350 - -config MFD_WM8350_I2C - bool "Support Wolfson Microelectronics WM8350 with I2C" - select MFD_WM8350 - depends on I2C=y && GENERIC_HARDIRQS - help - The WM8350 is an integrated audio and power management - subsystem with watchdog and RTC functionality for embedded - systems. This option enables core support for the WM8350 with - I2C as the control interface. Additional options must be - selected to enable support for the functionality of the chip. - -config MFD_WM8994 - bool "Support Wolfson Microelectronics WM8994" - select MFD_CORE - select REGMAP_I2C - select REGMAP_IRQ - depends on I2C=y && GENERIC_HARDIRQS - help - The WM8994 is a highly integrated hi-fi CODEC designed for - smartphone applicatiosn. As well as audio functionality it - has on board GPIO and regulator functionality which is - supported via the relevant subsystems. This driver provides - core support for the WM8994, in order to use the actual - functionaltiy of the device other drivers must be enabled. - -config MFD_PCF50633 - tristate "Support for NXP PCF50633" - depends on I2C - select REGMAP_I2C - help - Say yes here if you have NXP PCF50633 chip on your board. - This core driver provides register access and IRQ handling - facilities, and registers devices for the various functions - so that function-specific drivers can bind to them. - -config PCF50633_ADC - tristate "Support for NXP PCF50633 ADC" - depends on MFD_PCF50633 - help - Say yes here if you want to include support for ADC in the - NXP PCF50633 chip. - -config PCF50633_GPIO - tristate "Support for NXP PCF50633 GPIO" - depends on MFD_PCF50633 - help - Say yes here if you want to include support GPIO for pins on - the PCF50633 chip. - -config MFD_MC13783 - tristate - -config MFD_MC13XXX - tristate "Support Freescale MC13783 and MC13892" - depends on SPI_MASTER - select MFD_CORE - select MFD_MC13783 - help - Support for the Freescale (Atlas) PMIC and audio CODECs - MC13783 and MC13892. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device. - -config ABX500_CORE - bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" - default y if ARCH_U300 || ARCH_U8500 - help - Say yes here if you have the ABX500 Mixed Signal IC family - chips. This core driver expose register access functions. - Functionality specific drivers using these functions can - remain unchanged when IC changes. Binding of the functions to - actual register access is done by the IC core driver. - -config AB3100_CORE - bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions" - depends on I2C=y && ABX500_CORE - select MFD_CORE - default y if ARCH_U300 - help - Select this to enable the AB3100 Mixed Signal IC core - functionality. This connects to a AB3100 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 AB3100 such as battery-backed RTC, charging control, - LEDs, vibrator, system power and temperature, power management - and ALSA sound. - -config AB3100_OTP - tristate "ST-Ericsson AB3100 OTP functions" - depends on AB3100_CORE - default y if AB3100_CORE - help - Select this to enable the AB3100 Mixed Signal IC OTP (one-time - programmable memory) support. This exposes a sysfs file to read - out OTP values. - -config EZX_PCAP - bool "PCAP Support" - depends on GENERIC_HARDIRQS && SPI_MASTER - help - This enables the PCAP ASIC present on EZX Phones. This is - 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 - bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" - depends on GENERIC_HARDIRQS && ABX500_CORE - select MFD_CORE - help - Select this option to enable access to AB8500 power management - chip. This connects to U8500 either on the SSP/SPI bus (deprecated - since hardware version v1.0) or the I2C bus via PRCMU. It also adds - the irq_chip parts for handling the Mixed Signal chip events. - This chip embeds various other multimedia funtionalities as well. - -config AB8500_I2C_CORE - bool "AB8500 register access via PRCMU I2C" - depends on AB8500_CORE && MFD_DB8500_PRCMU - default y - help - This enables register access to the AB8500 chip via PRCMU I2C. - The AB8500 chip can be accessed via SPI or I2C. On DB8500 hardware - the I2C bus is connected to the Power Reset - and Mangagement Unit, PRCMU. - -config AB8500_DEBUG - bool "Enable debug info via debugfs" - depends on AB8500_CORE && DEBUG_FS - default y if DEBUG_FS - help - Select this option if you want debug information using the debug - filesystem, debugfs. - -config AB8500_GPADC - bool "AB8500 GPADC driver" - depends on AB8500_CORE && REGULATOR_AB8500 - default y - help - AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage - -config MFD_DB8500_PRCMU - bool "ST-Ericsson DB8500 Power Reset Control Management Unit" - depends on UX500_SOC_DB8500 - select MFD_CORE - help - Select this option to enable support for the DB8500 Power Reset - and Control Management Unit. This is basically an autonomous - system controller running an XP70 microprocessor, which is accessed - through a register map. - -config MFD_DB5500_PRCMU - bool "ST-Ericsson DB5500 Power Reset Control Management Unit" - depends on UX500_SOC_DB5500 - select MFD_CORE - help - Select this option to enable support for the DB5500 Power Reset - and Control Management Unit. This is basically an autonomous - system controller running an XP70 microprocessor, which is accessed - through a register map. - -config MFD_CS5535 - tristate "Support for CS5535 and CS5536 southbridge core functions" - select MFD_CORE - depends on PCI && X86 - ---help--- - This is the core driver for CS5535/CS5536 MFD functions. This is - necessary for using the board's GPIO and MFGPT functionality. - -config MFD_TIMBERDALE - tristate "Support for the Timberdale FPGA" - select MFD_CORE - depends on PCI && GPIOLIB - ---help--- - This is the core driver for the timberdale FPGA. This device is a - multifunction device which exposes numerous platform devices. - - The timberdale FPGA can be found on the Intel Atom development board - for in-vehicle infontainment, called Russellville. - -config LPC_SCH - tristate "Intel SCH LPC" - depends on PCI - select MFD_CORE - help - LPC bridge function of the Intel SCH provides support for - System Management Bus and General Purpose I/O. - -config MFD_RDC321X - tristate "Support for RDC-R321x southbridge" - select MFD_CORE - depends on PCI - help - Say yes here if you want to have support for the RDC R-321x SoC - southbridge which provides access to GPIOs and Watchdog using the - southbridge PCI device configuration space. - -config MFD_JANZ_CMODIO - tristate "Support for Janz CMOD-IO PCI MODULbus Carrier Board" - select MFD_CORE - depends on PCI - help - This is the core driver for the Janz CMOD-IO PCI MODULbus - carrier board. This device is a PCI to MODULbus bridge which may - host many different types of MODULbus daughterboards, including - CAN and GPIO controllers. - -config MFD_JZ4740_ADC - bool "Support for the JZ4740 SoC ADC core" - select MFD_CORE - select GENERIC_IRQ_CHIP - depends on MACH_JZ4740 - help - Say yes here if you want support for the ADC unit in the JZ4740 SoC. - This driver is necessary for jz4740-battery and jz4740-hwmon driver. - -config MFD_VX855 - tristate "Support for VIA VX855/VX875 integrated south bridge" - depends on PCI - select MFD_CORE - help - Say yes here to enable support for various functions of the - VIA VX855/VX875 south bridge. You will need to enable the vx855_spi - and/or vx855_gpio drivers for this to do anything useful. - -config MFD_WL1273_CORE - tristate "Support for TI WL1273 FM radio." - depends on I2C - select MFD_CORE - default n - help - This is the core driver for the TI WL1273 FM radio. This MFD - driver connects the radio-wl1273 V4L2 module and the wl1273 - audio codec. - -config MFD_OMAP_USB_HOST - bool "Support OMAP USBHS core driver" - depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3 - default y - help - This is the core driver for the OAMP EHCI and OHCI drivers. - This MFD driver does the required setup functionalities for - OMAP USB Host drivers. - -config MFD_PM8XXX - tristate - -config MFD_PM8921_CORE - tristate "Qualcomm PM8921 PMIC chip" - depends on MSM_SSBI - select MFD_CORE - select MFD_PM8XXX - help - If you say yes to this option, support will be included for the - built-in PM8921 PMIC chip. - - This is required if your board has a PM8921 and uses its features, - such as: MPPs, GPIOs, regulators, interrupts, and PWM. - - Say M here if you want to include support for PM8921 chip as a module. - This will build a module called "pm8921-core". - -config MFD_PM8XXX_IRQ - bool "Support for Qualcomm PM8xxx IRQ features" - depends on MFD_PM8XXX - default y if MFD_PM8XXX - help - This is the IRQ driver for Qualcomm PM 8xxx PMIC chips. - - This is required to use certain other PM 8xxx features, such as GPIO - and MPP. - -config TPS65911_COMPARATOR - tristate - -config MFD_TPS65090 - bool "TPS65090 Power Management chips" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - select REGMAP_I2C - help - If you say yes here you get support for the TPS65090 series of - Power Management chips. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device. - -config VT1603_CORE - bool "WMT VT1603 Support" - select MFD_CORE -choice - prompt "VT1603 control bus select" - default VT1603_IOCTRL_SPI - depends on VT1603_CORE -config VT1603_IOCTRL_SPI - bool "SPI" - ---help--- - Say Y here if you want to use SPI bus. -config VT1603_IOCTRL_I2C - bool "I2C" - ---help--- - Say Y here if you want to use I2C bus. -endchoice - - -config MFD_AAT2870_CORE - bool "Support for the AnalogicTech AAT2870" - select MFD_CORE - depends on I2C=y && GPIOLIB - help - If you say yes here you get support for the AAT2870. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device. - -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. - -config MFD_RC5T583 - bool "Ricoh RC5T583 Power Management system device" - depends on I2C=y && GENERIC_HARDIRQS - select MFD_CORE - select REGMAP_I2C - help - Select this option to get support for the RICOH583 Power - Management system device. - This driver provides common support for accessing the device - through i2c interface. The device supports multiple sub-devices - like GPIO, interrupts, RTC, LDO and DCDC regulators, onkey. - Additional drivers must be enabled in order to use the - different functionality of the device. - -config MFD_ANATOP - bool "Support for Freescale i.MX on-chip ANATOP controller" - depends on SOC_IMX6Q - help - Select this option to enable Freescale i.MX on-chip ANATOP - MFD controller. This controller embeds regulator and - thermal devices for Freescale i.MX platforms. - -source "drivers/mfd/gmt/Kconfig" - -endmenu -endif - -menu "Multimedia Capabilities Port drivers" - depends on ARCH_SA1100 - -config MCP - tristate - -# Interface drivers -config MCP_SA11X0 - tristate "Support SA11x0 MCP interface" - depends on ARCH_SA1100 - select MCP - -# Chip drivers -config MCP_UCB1200 - bool "Support for UCB1200 / UCB1300" - depends on MCP_SA11X0 - select MCP - -config MCP_UCB1200_TS - tristate "Touchscreen interface support" - depends on MCP_UCB1200 && INPUT - -endmenu diff --git a/ANDROID_3.4.5/drivers/mfd/Makefile b/ANDROID_3.4.5/drivers/mfd/Makefile deleted file mode 100644 index f978b2f9..00000000 --- a/ANDROID_3.4.5/drivers/mfd/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# -# Makefile for multifunction miscellaneous devices -# - -88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o -obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o -obj-$(CONFIG_MFD_SM501) += sm501.o -obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o - -obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o -obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o -obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o - -obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o -obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o -obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o - -obj-$(CONFIG_MFD_STMPE) += stmpe.o -obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o -obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o -obj-$(CONFIG_MFD_TC3589X) += tc3589x.o -obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o -obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o -obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o - -obj-$(CONFIG_MFD_WM8400) += wm8400-core.o -wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o -wm831x-objs += wm831x-auxadc.o -obj-$(CONFIG_MFD_WM831X) += wm831x.o -obj-$(CONFIG_MFD_WM831X_I2C) += wm831x-i2c.o -obj-$(CONFIG_MFD_WM831X_SPI) += wm831x-spi.o -wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o -wm8350-objs += wm8350-irq.o -obj-$(CONFIG_MFD_WM8350) += wm8350.o -obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o -obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o - -obj-$(CONFIG_TPS6105X) += tps6105x.o -obj-$(CONFIG_TPS65010) += tps65010.o -obj-$(CONFIG_TPS6507X) += tps6507x.o -obj-$(CONFIG_MFD_TPS65217) += tps65217.o -obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o -tps65912-objs := tps65912-core.o tps65912-irq.o -obj-$(CONFIG_MFD_TPS65912) += tps65912.o -obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o -obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o -obj-$(CONFIG_MENELAUS) += menelaus.o - -obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o -obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o -obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o -obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o -obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o -obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o - -obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o - -obj-$(CONFIG_MFD_CORE) += mfd-core.o - -obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o - -obj-$(CONFIG_MCP) += mcp-core.o -obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o -obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o -obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o - -ifeq ($(CONFIG_SA1100_ASSABET),y) -obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o -endif -obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o - -obj-$(CONFIG_PMIC_DA903X) += da903x.o - -obj-$(CONFIG_PMIC_DA9052) += da9052-core.o -obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o -obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o - -max8925-objs := max8925-core.o max8925-i2c.o -obj-$(CONFIG_MFD_MAX8925) += max8925.o -obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o -obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o - -pcf50633-objs := pcf50633-core.o pcf50633-irq.o -obj-$(CONFIG_MFD_PCF50633) += pcf50633.o -obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o -obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o -obj-$(CONFIG_ABX500_CORE) += abx500-core.o -obj-$(CONFIG_AB3100_CORE) += ab3100-core.o -obj-$(CONFIG_AB3100_OTP) += ab3100-otp.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_DEBUG) += ab8500-debugfs.o -obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o -obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o -# ab8500-i2c need to come after db8500-prcmu (which provides the channel) -obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o -obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o -obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o -obj-$(CONFIG_PMIC_ADP5520) += adp5520.o -obj-$(CONFIG_LPC_SCH) += lpc_sch.o -obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o -obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o -obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o -obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o -obj-$(CONFIG_MFD_VX855) += vx855.o -obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o -obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o -obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o -obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o -obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o -obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o -obj-$(CONFIG_MFD_TPS65090) += tps65090.o -obj-$(CONFIG_VT1603_CORE) += vt1603-core.o - -obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o -obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o -obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o -obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o -obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o -obj-$(CONFIG_VT1603_CORE) += vt1603-core.o -obj-$(CONFIG_MFD_GMT) += gmt/ diff --git a/ANDROID_3.4.5/drivers/mfd/aat2870-core.c b/ANDROID_3.4.5/drivers/mfd/aat2870-core.c deleted file mode 100644 index 44a3fdba..00000000 --- a/ANDROID_3.4.5/drivers/mfd/aat2870-core.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * linux/drivers/mfd/aat2870-core.c - * - * Copyright (c) 2011, NVIDIA Corporation. - * Author: Jin Park <jinyoungp@nvidia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/debugfs.h> -#include <linux/slab.h> -#include <linux/uaccess.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/mfd/core.h> -#include <linux/mfd/aat2870.h> -#include <linux/regulator/machine.h> - -static struct aat2870_register aat2870_regs[AAT2870_REG_NUM] = { - /* readable, writeable, value */ - { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */ - { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */ - { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */ - { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */ - { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */ - { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */ - { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */ - { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */ - { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */ - { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */ - { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */ - { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */ - { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */ - { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */ - { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */ - { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */ - { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */ - { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */ - { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */ - { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */ - { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */ - { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */ - { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */ - { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */ - { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */ - { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */ - { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */ - { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */ - { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */ - { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */ - { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */ - { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */ - { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */ - { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */ - { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */ - { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */ - { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */ - { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */ - { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */ -}; - -static struct mfd_cell aat2870_devs[] = { - { - .name = "aat2870-backlight", - .id = AAT2870_ID_BL, - .pdata_size = sizeof(struct aat2870_bl_platform_data), - }, - { - .name = "aat2870-regulator", - .id = AAT2870_ID_LDOA, - .pdata_size = sizeof(struct regulator_init_data), - }, - { - .name = "aat2870-regulator", - .id = AAT2870_ID_LDOB, - .pdata_size = sizeof(struct regulator_init_data), - }, - { - .name = "aat2870-regulator", - .id = AAT2870_ID_LDOC, - .pdata_size = sizeof(struct regulator_init_data), - }, - { - .name = "aat2870-regulator", - .id = AAT2870_ID_LDOD, - .pdata_size = sizeof(struct regulator_init_data), - }, -}; - -static int __aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val) -{ - int ret; - - if (addr >= AAT2870_REG_NUM) { - dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr); - return -EINVAL; - } - - if (!aat2870->reg_cache[addr].readable) { - *val = aat2870->reg_cache[addr].value; - goto out; - } - - ret = i2c_master_send(aat2870->client, &addr, 1); - if (ret < 0) - return ret; - if (ret != 1) - return -EIO; - - ret = i2c_master_recv(aat2870->client, val, 1); - if (ret < 0) - return ret; - if (ret != 1) - return -EIO; - -out: - dev_dbg(aat2870->dev, "read: addr=0x%02x, val=0x%02x\n", addr, *val); - return 0; -} - -static int __aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val) -{ - u8 msg[2]; - int ret; - - if (addr >= AAT2870_REG_NUM) { - dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr); - return -EINVAL; - } - - if (!aat2870->reg_cache[addr].writeable) { - dev_err(aat2870->dev, "Address 0x%02x is not writeable\n", - addr); - return -EINVAL; - } - - msg[0] = addr; - msg[1] = val; - ret = i2c_master_send(aat2870->client, msg, 2); - if (ret < 0) - return ret; - if (ret != 2) - return -EIO; - - aat2870->reg_cache[addr].value = val; - - dev_dbg(aat2870->dev, "write: addr=0x%02x, val=0x%02x\n", addr, val); - return 0; -} - -static int aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val) -{ - int ret; - - mutex_lock(&aat2870->io_lock); - ret = __aat2870_read(aat2870, addr, val); - mutex_unlock(&aat2870->io_lock); - - return ret; -} - -static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val) -{ - int ret; - - mutex_lock(&aat2870->io_lock); - ret = __aat2870_write(aat2870, addr, val); - mutex_unlock(&aat2870->io_lock); - - return ret; -} - -static int aat2870_update(struct aat2870_data *aat2870, u8 addr, u8 mask, - u8 val) -{ - int change; - u8 old_val, new_val; - int ret; - - mutex_lock(&aat2870->io_lock); - - ret = __aat2870_read(aat2870, addr, &old_val); - if (ret) - goto out_unlock; - - new_val = (old_val & ~mask) | (val & mask); - change = old_val != new_val; - if (change) - ret = __aat2870_write(aat2870, addr, new_val); - -out_unlock: - mutex_unlock(&aat2870->io_lock); - - return ret; -} - -static inline void aat2870_enable(struct aat2870_data *aat2870) -{ - if (aat2870->en_pin >= 0) - gpio_set_value(aat2870->en_pin, 1); - - aat2870->is_enable = 1; -} - -static inline void aat2870_disable(struct aat2870_data *aat2870) -{ - if (aat2870->en_pin >= 0) - gpio_set_value(aat2870->en_pin, 0); - - aat2870->is_enable = 0; -} - -#ifdef CONFIG_DEBUG_FS -static ssize_t aat2870_dump_reg(struct aat2870_data *aat2870, char *buf) -{ - u8 addr, val; - ssize_t count = 0; - int ret; - - count += sprintf(buf, "aat2870 registers\n"); - for (addr = 0; addr < AAT2870_REG_NUM; addr++) { - count += sprintf(buf + count, "0x%02x: ", addr); - if (count >= PAGE_SIZE - 1) - break; - - ret = aat2870->read(aat2870, addr, &val); - if (ret == 0) - count += snprintf(buf + count, PAGE_SIZE - count, - "0x%02x", val); - else - count += snprintf(buf + count, PAGE_SIZE - count, - "<read fail: %d>", ret); - - if (count >= PAGE_SIZE - 1) - break; - - count += snprintf(buf + count, PAGE_SIZE - count, "\n"); - if (count >= PAGE_SIZE - 1) - break; - } - - /* Truncate count; min() would cause a warning */ - if (count >= PAGE_SIZE) - count = PAGE_SIZE - 1; - - return count; -} - -static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct aat2870_data *aat2870 = file->private_data; - char *buf; - ssize_t ret; - - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = aat2870_dump_reg(aat2870, buf); - if (ret >= 0) - ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); - - kfree(buf); - - return ret; -} - -static ssize_t aat2870_reg_write_file(struct file *file, - const char __user *user_buf, size_t count, - loff_t *ppos) -{ - struct aat2870_data *aat2870 = file->private_data; - char buf[32]; - ssize_t buf_size; - char *start = buf; - unsigned long addr, val; - int ret; - - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) { - dev_err(aat2870->dev, "Failed to copy from user\n"); - return -EFAULT; - } - buf[buf_size] = 0; - - while (*start == ' ') - start++; - - addr = simple_strtoul(start, &start, 16); - if (addr >= AAT2870_REG_NUM) { - dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr); - return -EINVAL; - } - - while (*start == ' ') - start++; - - if (strict_strtoul(start, 16, &val)) - return -EINVAL; - - ret = aat2870->write(aat2870, (u8)addr, (u8)val); - if (ret) - return ret; - - return buf_size; -} - -static const struct file_operations aat2870_reg_fops = { - .open = simple_open, - .read = aat2870_reg_read_file, - .write = aat2870_reg_write_file, -}; - -static void aat2870_init_debugfs(struct aat2870_data *aat2870) -{ - aat2870->dentry_root = debugfs_create_dir("aat2870", NULL); - if (!aat2870->dentry_root) { - dev_warn(aat2870->dev, - "Failed to create debugfs root directory\n"); - return; - } - - aat2870->dentry_reg = debugfs_create_file("regs", 0644, - aat2870->dentry_root, - aat2870, &aat2870_reg_fops); - if (!aat2870->dentry_reg) - dev_warn(aat2870->dev, - "Failed to create debugfs register file\n"); -} - -static void aat2870_uninit_debugfs(struct aat2870_data *aat2870) -{ - debugfs_remove_recursive(aat2870->dentry_root); -} -#else -static inline void aat2870_init_debugfs(struct aat2870_data *aat2870) -{ -} - -static inline void aat2870_uninit_debugfs(struct aat2870_data *aat2870) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static int aat2870_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct aat2870_platform_data *pdata = client->dev.platform_data; - struct aat2870_data *aat2870; - int i, j; - int ret = 0; - - aat2870 = kzalloc(sizeof(struct aat2870_data), GFP_KERNEL); - if (!aat2870) { - dev_err(&client->dev, - "Failed to allocate memory for aat2870\n"); - ret = -ENOMEM; - goto out; - } - - aat2870->dev = &client->dev; - dev_set_drvdata(aat2870->dev, aat2870); - - aat2870->client = client; - i2c_set_clientdata(client, aat2870); - - aat2870->reg_cache = aat2870_regs; - - if (pdata->en_pin < 0) - aat2870->en_pin = -1; - else - aat2870->en_pin = pdata->en_pin; - - aat2870->init = pdata->init; - aat2870->uninit = pdata->uninit; - aat2870->read = aat2870_read; - aat2870->write = aat2870_write; - aat2870->update = aat2870_update; - - mutex_init(&aat2870->io_lock); - - if (aat2870->init) - aat2870->init(aat2870); - - if (aat2870->en_pin >= 0) { - ret = gpio_request_one(aat2870->en_pin, GPIOF_OUT_INIT_HIGH, - "aat2870-en"); - if (ret < 0) { - dev_err(&client->dev, - "Failed to request GPIO %d\n", aat2870->en_pin); - goto out_kfree; - } - } - - aat2870_enable(aat2870); - - for (i = 0; i < pdata->num_subdevs; i++) { - for (j = 0; j < ARRAY_SIZE(aat2870_devs); j++) { - if ((pdata->subdevs[i].id == aat2870_devs[j].id) && - !strcmp(pdata->subdevs[i].name, - aat2870_devs[j].name)) { - aat2870_devs[j].platform_data = - pdata->subdevs[i].platform_data; - break; - } - } - } - - ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, - ARRAY_SIZE(aat2870_devs), NULL, 0); - if (ret != 0) { - dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); - goto out_disable; - } - - aat2870_init_debugfs(aat2870); - - return 0; - -out_disable: - aat2870_disable(aat2870); - if (aat2870->en_pin >= 0) - gpio_free(aat2870->en_pin); -out_kfree: - kfree(aat2870); -out: - return ret; -} - -static int aat2870_i2c_remove(struct i2c_client *client) -{ - struct aat2870_data *aat2870 = i2c_get_clientdata(client); - - aat2870_uninit_debugfs(aat2870); - - mfd_remove_devices(aat2870->dev); - aat2870_disable(aat2870); - if (aat2870->en_pin >= 0) - gpio_free(aat2870->en_pin); - if (aat2870->uninit) - aat2870->uninit(aat2870); - kfree(aat2870); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int aat2870_i2c_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct aat2870_data *aat2870 = i2c_get_clientdata(client); - - aat2870_disable(aat2870); - - return 0; -} - -static int aat2870_i2c_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct aat2870_data *aat2870 = i2c_get_clientdata(client); - struct aat2870_register *reg = NULL; - int i; - - aat2870_enable(aat2870); - - /* restore registers */ - for (i = 0; i < AAT2870_REG_NUM; i++) { - reg = &aat2870->reg_cache[i]; - if (reg->writeable) - aat2870->write(aat2870, i, reg->value); - } - - return 0; -} -#endif /* CONFIG_PM_SLEEP */ - -static SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend, - aat2870_i2c_resume); - -static const struct i2c_device_id aat2870_i2c_id_table[] = { - { "aat2870", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, aat2870_i2c_id_table); - -static struct i2c_driver aat2870_i2c_driver = { - .driver = { - .name = "aat2870", - .owner = THIS_MODULE, - .pm = &aat2870_pm_ops, - }, - .probe = aat2870_i2c_probe, - .remove = aat2870_i2c_remove, - .id_table = aat2870_i2c_id_table, -}; - -static int __init aat2870_init(void) -{ - return i2c_add_driver(&aat2870_i2c_driver); -} -subsys_initcall(aat2870_init); - -static void __exit aat2870_exit(void) -{ - i2c_del_driver(&aat2870_i2c_driver); -} -module_exit(aat2870_exit); - -MODULE_DESCRIPTION("Core support for the AnalogicTech AAT2870"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab3100-core.c b/ANDROID_3.4.5/drivers/mfd/ab3100-core.c deleted file mode 100644 index 1efad20f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab3100-core.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (C) 2007-2010 ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - * Low-level core for exclusive access to the AB3100 IC on the I2C bus - * and some basic chip-configuration. - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ - -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <linux/list.h> -#include <linux/notifier.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/random.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/uaccess.h> -#include <linux/mfd/core.h> -#include <linux/mfd/abx500.h> - -/* These are the only registers inside AB3100 used in this main file */ - -/* Interrupt event registers */ -#define AB3100_EVENTA1 0x21 -#define AB3100_EVENTA2 0x22 -#define AB3100_EVENTA3 0x23 - -/* AB3100 DAC converter registers */ -#define AB3100_DIS 0x00 -#define AB3100_D0C 0x01 -#define AB3100_D1C 0x02 -#define AB3100_D2C 0x03 -#define AB3100_D3C 0x04 - -/* Chip ID register */ -#define AB3100_CID 0x20 - -/* AB3100 interrupt registers */ -#define AB3100_IMRA1 0x24 -#define AB3100_IMRA2 0x25 -#define AB3100_IMRA3 0x26 -#define AB3100_IMRB1 0x2B -#define AB3100_IMRB2 0x2C -#define AB3100_IMRB3 0x2D - -/* System Power Monitoring and control registers */ -#define AB3100_MCA 0x2E -#define AB3100_MCB 0x2F - -/* SIM power up */ -#define AB3100_SUP 0x50 - -/* - * I2C communication - * - * The AB3100 is usually assigned address 0x48 (7-bit) - * The chip is defined in the platform i2c_board_data section. - */ -static int ab3100_get_chip_id(struct device *dev) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - - return (int)ab3100->chip_id; -} - -static int ab3100_set_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 regval) -{ - u8 regandval[2] = {reg, regval}; - int err; - - err = mutex_lock_interruptible(&ab3100->access_mutex); - if (err) - return err; - - /* - * A two-byte write message with the first byte containing the register - * number and the second byte containing the value to be written - * effectively sets a register in the AB3100. - */ - err = i2c_master_send(ab3100->i2c_client, regandval, 2); - if (err < 0) { - dev_err(ab3100->dev, - "write error (write register): %d\n", - err); - } else if (err != 2) { - dev_err(ab3100->dev, - "write error (write register) " - "%d bytes transferred (expected 2)\n", - err); - err = -EIO; - } else { - /* All is well */ - err = 0; - } - mutex_unlock(&ab3100->access_mutex); - return err; -} - -static int set_register_interruptible(struct device *dev, - u8 bank, u8 reg, u8 value) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - - return ab3100_set_register_interruptible(ab3100, reg, value); -} - -/* - * The test registers exist at an I2C bus address up one - * from the ordinary base. They are not supposed to be used - * in production code, but sometimes you have to do that - * anyway. It's currently only used from this file so declare - * it static and do not export. - */ -static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 regval) -{ - u8 regandval[2] = {reg, regval}; - int err; - - err = mutex_lock_interruptible(&ab3100->access_mutex); - if (err) - return err; - - err = i2c_master_send(ab3100->testreg_client, regandval, 2); - if (err < 0) { - dev_err(ab3100->dev, - "write error (write test register): %d\n", - err); - } else if (err != 2) { - dev_err(ab3100->dev, - "write error (write test register) " - "%d bytes transferred (expected 2)\n", - err); - err = -EIO; - } else { - /* All is well */ - err = 0; - } - mutex_unlock(&ab3100->access_mutex); - - return err; -} - -static int ab3100_get_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 *regval) -{ - int err; - - err = mutex_lock_interruptible(&ab3100->access_mutex); - if (err) - return err; - - /* - * AB3100 require an I2C "stop" command between each message, else - * it will not work. The only way of achieveing this with the - * message transport layer is to send the read and write messages - * separately. - */ - err = i2c_master_send(ab3100->i2c_client, ®, 1); - if (err < 0) { - dev_err(ab3100->dev, - "write error (send register address): %d\n", - err); - goto get_reg_out_unlock; - } else if (err != 1) { - dev_err(ab3100->dev, - "write error (send register address) " - "%d bytes transferred (expected 1)\n", - err); - err = -EIO; - goto get_reg_out_unlock; - } else { - /* All is well */ - err = 0; - } - - err = i2c_master_recv(ab3100->i2c_client, regval, 1); - if (err < 0) { - dev_err(ab3100->dev, - "write error (read register): %d\n", - err); - goto get_reg_out_unlock; - } else if (err != 1) { - dev_err(ab3100->dev, - "write error (read register) " - "%d bytes transferred (expected 1)\n", - err); - err = -EIO; - goto get_reg_out_unlock; - } else { - /* All is well */ - err = 0; - } - - get_reg_out_unlock: - mutex_unlock(&ab3100->access_mutex); - return err; -} - -static int get_register_interruptible(struct device *dev, u8 bank, u8 reg, - u8 *value) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - - return ab3100_get_register_interruptible(ab3100, reg, value); -} - -static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, - u8 first_reg, u8 *regvals, u8 numregs) -{ - int err; - - if (ab3100->chip_id == 0xa0 || - ab3100->chip_id == 0xa1) - /* These don't support paged reads */ - return -EIO; - - err = mutex_lock_interruptible(&ab3100->access_mutex); - if (err) - return err; - - /* - * Paged read also require an I2C "stop" command. - */ - err = i2c_master_send(ab3100->i2c_client, &first_reg, 1); - if (err < 0) { - dev_err(ab3100->dev, - "write error (send first register address): %d\n", - err); - goto get_reg_page_out_unlock; - } else if (err != 1) { - dev_err(ab3100->dev, - "write error (send first register address) " - "%d bytes transferred (expected 1)\n", - err); - err = -EIO; - goto get_reg_page_out_unlock; - } - - err = i2c_master_recv(ab3100->i2c_client, regvals, numregs); - if (err < 0) { - dev_err(ab3100->dev, - "write error (read register page): %d\n", - err); - goto get_reg_page_out_unlock; - } else if (err != numregs) { - dev_err(ab3100->dev, - "write error (read register page) " - "%d bytes transferred (expected %d)\n", - err, numregs); - err = -EIO; - goto get_reg_page_out_unlock; - } - - /* All is well */ - err = 0; - - get_reg_page_out_unlock: - mutex_unlock(&ab3100->access_mutex); - return err; -} - -static int get_register_page_interruptible(struct device *dev, u8 bank, - u8 first_reg, u8 *regvals, u8 numregs) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - - return ab3100_get_register_page_interruptible(ab3100, - first_reg, regvals, numregs); -} - -static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 andmask, u8 ormask) -{ - u8 regandval[2] = {reg, 0}; - int err; - - err = mutex_lock_interruptible(&ab3100->access_mutex); - if (err) - return err; - - /* First read out the target register */ - err = i2c_master_send(ab3100->i2c_client, ®, 1); - if (err < 0) { - dev_err(ab3100->dev, - "write error (maskset send address): %d\n", - err); - goto get_maskset_unlock; - } else if (err != 1) { - dev_err(ab3100->dev, - "write error (maskset send address) " - "%d bytes transferred (expected 1)\n", - err); - err = -EIO; - goto get_maskset_unlock; - } - - err = i2c_master_recv(ab3100->i2c_client, ®andval[1], 1); - if (err < 0) { - dev_err(ab3100->dev, - "write error (maskset read register): %d\n", - err); - goto get_maskset_unlock; - } else if (err != 1) { - dev_err(ab3100->dev, - "write error (maskset read register) " - "%d bytes transferred (expected 1)\n", - err); - err = -EIO; - goto get_maskset_unlock; - } - - /* Modify the register */ - regandval[1] &= andmask; - regandval[1] |= ormask; - - /* Write the register */ - err = i2c_master_send(ab3100->i2c_client, regandval, 2); - if (err < 0) { - dev_err(ab3100->dev, - "write error (write register): %d\n", - err); - goto get_maskset_unlock; - } else if (err != 2) { - dev_err(ab3100->dev, - "write error (write register) " - "%d bytes transferred (expected 2)\n", - err); - err = -EIO; - goto get_maskset_unlock; - } - - /* All is well */ - err = 0; - - get_maskset_unlock: - mutex_unlock(&ab3100->access_mutex); - return err; -} - -static int mask_and_set_register_interruptible(struct device *dev, u8 bank, - u8 reg, u8 bitmask, u8 bitvalues) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - - return ab3100_mask_and_set_register_interruptible(ab3100, - reg, bitmask, (bitmask & bitvalues)); -} - -/* - * Register a simple callback for handling any AB3100 events. - */ -int ab3100_event_register(struct ab3100 *ab3100, - struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&ab3100->event_subscribers, - nb); -} -EXPORT_SYMBOL(ab3100_event_register); - -/* - * Remove a previously registered callback. - */ -int ab3100_event_unregister(struct ab3100 *ab3100, - struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&ab3100->event_subscribers, - nb); -} -EXPORT_SYMBOL(ab3100_event_unregister); - - -static int ab3100_event_registers_startup_state_get(struct device *dev, - u8 *event) -{ - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); - if (!ab3100->startup_events_read) - return -EAGAIN; /* Try again later */ - memcpy(event, ab3100->startup_events, 3); - return 0; -} - -static struct abx500_ops ab3100_ops = { - .get_chip_id = ab3100_get_chip_id, - .set_register = set_register_interruptible, - .get_register = get_register_interruptible, - .get_register_page = get_register_page_interruptible, - .set_register_page = NULL, - .mask_and_set_register = mask_and_set_register_interruptible, - .event_registers_startup_state_get = - ab3100_event_registers_startup_state_get, - .startup_irq_enabled = NULL, -}; - -/* - * This is a threaded interrupt handler so we can make some - * I2C calls etc. - */ -static irqreturn_t ab3100_irq_handler(int irq, void *data) -{ - struct ab3100 *ab3100 = data; - u8 event_regs[3]; - u32 fatevent; - int err; - - add_interrupt_randomness(irq); - - err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, - event_regs, 3); - if (err) - goto err_event; - - fatevent = (event_regs[0] << 16) | - (event_regs[1] << 8) | - event_regs[2]; - - if (!ab3100->startup_events_read) { - ab3100->startup_events[0] = event_regs[0]; - ab3100->startup_events[1] = event_regs[1]; - ab3100->startup_events[2] = event_regs[2]; - ab3100->startup_events_read = true; - } - /* - * The notified parties will have to mask out the events - * they're interested in and react to them. They will be - * notified on all events, then they use the fatevent value - * to determine if they're interested. - */ - blocking_notifier_call_chain(&ab3100->event_subscribers, - fatevent, NULL); - - dev_dbg(ab3100->dev, - "IRQ Event: 0x%08x\n", fatevent); - - return IRQ_HANDLED; - - err_event: - dev_dbg(ab3100->dev, - "error reading event status\n"); - return IRQ_HANDLED; -} - -#ifdef CONFIG_DEBUG_FS -/* - * Some debugfs entries only exposed if we're using debug - */ -static int ab3100_registers_print(struct seq_file *s, void *p) -{ - struct ab3100 *ab3100 = s->private; - u8 value; - u8 reg; - - seq_printf(s, "AB3100 registers:\n"); - - for (reg = 0; reg < 0xff; reg++) { - ab3100_get_register_interruptible(ab3100, reg, &value); - seq_printf(s, "[0x%x]: 0x%x\n", reg, value); - } - return 0; -} - -static int ab3100_registers_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab3100_registers_print, inode->i_private); -} - -static const struct file_operations ab3100_registers_fops = { - .open = ab3100_registers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -struct ab3100_get_set_reg_priv { - struct ab3100 *ab3100; - bool mode; -}; - -static ssize_t ab3100_get_set_reg(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ab3100_get_set_reg_priv *priv = file->private_data; - struct ab3100 *ab3100 = priv->ab3100; - char buf[32]; - ssize_t buf_size; - int regp; - unsigned long user_reg; - int err; - int i = 0; - - /* 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; - - /* - * The idea is here to parse a string which is either - * "0xnn" for reading a register, or "0xaa 0xbb" for - * writing 0xbb to the register 0xaa. First move past - * whitespace and then begin to parse the register. - */ - while ((i < buf_size) && (buf[i] == ' ')) - i++; - regp = i; - - /* - * Advance pointer to end of string then terminate - * the register string. This is needed to satisfy - * the strict_strtoul() function. - */ - while ((i < buf_size) && (buf[i] != ' ')) - i++; - buf[i] = '\0'; - - err = strict_strtoul(&buf[regp], 16, &user_reg); - if (err) - return err; - if (user_reg > 0xff) - return -EINVAL; - - /* Either we read or we write a register here */ - if (!priv->mode) { - /* Reading */ - u8 reg = (u8) user_reg; - u8 regvalue; - - ab3100_get_register_interruptible(ab3100, reg, ®value); - - dev_info(ab3100->dev, - "debug read AB3100 reg[0x%02x]: 0x%02x\n", - reg, regvalue); - } else { - int valp; - unsigned long user_value; - u8 reg = (u8) user_reg; - u8 value; - u8 regvalue; - - /* - * Writing, we need some value to write to - * the register so keep parsing the string - * from userspace. - */ - i++; - while ((i < buf_size) && (buf[i] == ' ')) - i++; - valp = i; - while ((i < buf_size) && (buf[i] != ' ')) - i++; - buf[i] = '\0'; - - err = strict_strtoul(&buf[valp], 16, &user_value); - if (err) - return err; - if (user_reg > 0xff) - return -EINVAL; - - value = (u8) user_value; - ab3100_set_register_interruptible(ab3100, reg, value); - ab3100_get_register_interruptible(ab3100, reg, ®value); - - dev_info(ab3100->dev, - "debug write reg[0x%02x] with 0x%02x, " - "after readback: 0x%02x\n", - reg, value, regvalue); - } - return buf_size; -} - -static const struct file_operations ab3100_get_set_reg_fops = { - .open = simple_open, - .write = ab3100_get_set_reg, - .llseek = noop_llseek, -}; - -static struct dentry *ab3100_dir; -static struct dentry *ab3100_reg_file; -static struct ab3100_get_set_reg_priv ab3100_get_priv; -static struct dentry *ab3100_get_reg_file; -static struct ab3100_get_set_reg_priv ab3100_set_priv; -static struct dentry *ab3100_set_reg_file; - -static void ab3100_setup_debugfs(struct ab3100 *ab3100) -{ - int err; - - ab3100_dir = debugfs_create_dir("ab3100", NULL); - if (!ab3100_dir) - goto exit_no_debugfs; - - ab3100_reg_file = debugfs_create_file("registers", - S_IRUGO, ab3100_dir, ab3100, - &ab3100_registers_fops); - if (!ab3100_reg_file) { - err = -ENOMEM; - goto exit_destroy_dir; - } - - ab3100_get_priv.ab3100 = ab3100; - ab3100_get_priv.mode = false; - ab3100_get_reg_file = debugfs_create_file("get_reg", - S_IWUSR, ab3100_dir, &ab3100_get_priv, - &ab3100_get_set_reg_fops); - if (!ab3100_get_reg_file) { - err = -ENOMEM; - goto exit_destroy_reg; - } - - ab3100_set_priv.ab3100 = ab3100; - ab3100_set_priv.mode = true; - ab3100_set_reg_file = debugfs_create_file("set_reg", - S_IWUSR, ab3100_dir, &ab3100_set_priv, - &ab3100_get_set_reg_fops); - if (!ab3100_set_reg_file) { - err = -ENOMEM; - goto exit_destroy_get_reg; - } - return; - - exit_destroy_get_reg: - debugfs_remove(ab3100_get_reg_file); - exit_destroy_reg: - debugfs_remove(ab3100_reg_file); - exit_destroy_dir: - debugfs_remove(ab3100_dir); - exit_no_debugfs: - return; -} -static inline void ab3100_remove_debugfs(void) -{ - debugfs_remove(ab3100_set_reg_file); - debugfs_remove(ab3100_get_reg_file); - debugfs_remove(ab3100_reg_file); - debugfs_remove(ab3100_dir); -} -#else -static inline void ab3100_setup_debugfs(struct ab3100 *ab3100) -{ -} -static inline void ab3100_remove_debugfs(void) -{ -} -#endif - -/* - * Basic set-up, datastructure creation/destruction and I2C interface. - * This sets up a default config in the AB3100 chip so that it - * will work as expected. - */ - -struct ab3100_init_setting { - u8 abreg; - u8 setting; -}; - -static const struct ab3100_init_setting __devinitconst -ab3100_init_settings[] = { - { - .abreg = AB3100_MCA, - .setting = 0x01 - }, { - .abreg = AB3100_MCB, - .setting = 0x30 - }, { - .abreg = AB3100_IMRA1, - .setting = 0x00 - }, { - .abreg = AB3100_IMRA2, - .setting = 0xFF - }, { - .abreg = AB3100_IMRA3, - .setting = 0x01 - }, { - .abreg = AB3100_IMRB1, - .setting = 0xBF - }, { - .abreg = AB3100_IMRB2, - .setting = 0xFF - }, { - .abreg = AB3100_IMRB3, - .setting = 0xFF - }, { - .abreg = AB3100_SUP, - .setting = 0x00 - }, { - .abreg = AB3100_DIS, - .setting = 0xF0 - }, { - .abreg = AB3100_D0C, - .setting = 0x00 - }, { - .abreg = AB3100_D1C, - .setting = 0x00 - }, { - .abreg = AB3100_D2C, - .setting = 0x00 - }, { - .abreg = AB3100_D3C, - .setting = 0x00 - }, -}; - -static int __devinit ab3100_setup(struct ab3100 *ab3100) -{ - int err = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) { - err = ab3100_set_register_interruptible(ab3100, - ab3100_init_settings[i].abreg, - ab3100_init_settings[i].setting); - if (err) - goto exit_no_setup; - } - - /* - * Special trick to make the AB3100 use the 32kHz clock (RTC) - * bit 3 in test register 0x02 is a special, undocumented test - * register bit that only exist in AB3100 P1E - */ - if (ab3100->chip_id == 0xc4) { - dev_warn(ab3100->dev, - "AB3100 P1E variant detected, " - "forcing chip to 32KHz\n"); - err = ab3100_set_test_register_interruptible(ab3100, - 0x02, 0x08); - } - - exit_no_setup: - return err; -} - -/* The subdevices of the AB3100 */ -static struct mfd_cell ab3100_devs[] = { - { - .name = "ab3100-dac", - .id = -1, - }, - { - .name = "ab3100-leds", - .id = -1, - }, - { - .name = "ab3100-power", - .id = -1, - }, - { - .name = "ab3100-regulators", - .id = -1, - }, - { - .name = "ab3100-sim", - .id = -1, - }, - { - .name = "ab3100-uart", - .id = -1, - }, - { - .name = "ab3100-rtc", - .id = -1, - }, - { - .name = "ab3100-charger", - .id = -1, - }, - { - .name = "ab3100-boost", - .id = -1, - }, - { - .name = "ab3100-adc", - .id = -1, - }, - { - .name = "ab3100-fuelgauge", - .id = -1, - }, - { - .name = "ab3100-vibrator", - .id = -1, - }, - { - .name = "ab3100-otp", - .id = -1, - }, - { - .name = "ab3100-codec", - .id = -1, - }, -}; - -struct ab_family_id { - u8 id; - char *name; -}; - -static const struct ab_family_id ids[] __devinitconst = { - /* AB3100 */ - { - .id = 0xc0, - .name = "P1A" - }, { - .id = 0xc1, - .name = "P1B" - }, { - .id = 0xc2, - .name = "P1C" - }, { - .id = 0xc3, - .name = "P1D" - }, { - .id = 0xc4, - .name = "P1E" - }, { - .id = 0xc5, - .name = "P1F/R1A" - }, { - .id = 0xc6, - .name = "P1G/R1A" - }, { - .id = 0xc7, - .name = "P2A/R2A" - }, { - .id = 0xc8, - .name = "P2B/R2B" - }, - /* AB3000 variants, not supported */ - { - .id = 0xa0 - }, { - .id = 0xa1 - }, { - .id = 0xa2 - }, { - .id = 0xa3 - }, { - .id = 0xa4 - }, { - .id = 0xa5 - }, { - .id = 0xa6 - }, { - .id = 0xa7 - }, - /* Terminator */ - { - .id = 0x00, - }, -}; - -static int __devinit ab3100_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct ab3100 *ab3100; - struct ab3100_platform_data *ab3100_plf_data = - client->dev.platform_data; - int err; - int i; - - ab3100 = kzalloc(sizeof(struct ab3100), GFP_KERNEL); - if (!ab3100) { - dev_err(&client->dev, "could not allocate AB3100 device\n"); - return -ENOMEM; - } - - /* Initialize data structure */ - mutex_init(&ab3100->access_mutex); - BLOCKING_INIT_NOTIFIER_HEAD(&ab3100->event_subscribers); - - ab3100->i2c_client = client; - ab3100->dev = &ab3100->i2c_client->dev; - - i2c_set_clientdata(client, ab3100); - - /* Read chip ID register */ - err = ab3100_get_register_interruptible(ab3100, AB3100_CID, - &ab3100->chip_id); - if (err) { - dev_err(&client->dev, - "could not communicate with the AB3100 analog " - "baseband chip\n"); - goto exit_no_detect; - } - - for (i = 0; ids[i].id != 0x0; i++) { - if (ids[i].id == ab3100->chip_id) { - if (ids[i].name != NULL) { - snprintf(&ab3100->chip_name[0], - sizeof(ab3100->chip_name) - 1, - "AB3100 %s", - ids[i].name); - break; - } else { - dev_err(&client->dev, - "AB3000 is not supported\n"); - goto exit_no_detect; - } - } - } - - if (ids[i].id == 0x0) { - dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", - ab3100->chip_id); - dev_err(&client->dev, "accepting it anyway. Please update " - "the driver.\n"); - goto exit_no_detect; - } - - dev_info(&client->dev, "Detected chip: %s\n", - &ab3100->chip_name[0]); - - /* Attach a second dummy i2c_client to the test register address */ - ab3100->testreg_client = i2c_new_dummy(client->adapter, - client->addr + 1); - if (!ab3100->testreg_client) { - err = -ENOMEM; - goto exit_no_testreg_client; - } - - err = ab3100_setup(ab3100); - if (err) - goto exit_no_setup; - - err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler, - IRQF_ONESHOT, "ab3100-core", ab3100); - /* This real unpredictable IRQ is of course sampled for entropy */ - rand_initialize_irq(client->irq); - - if (err) - goto exit_no_irq; - - err = abx500_register_ops(&client->dev, &ab3100_ops); - if (err) - goto exit_no_ops; - - /* Set up and register the platform devices. */ - for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) { - ab3100_devs[i].platform_data = ab3100_plf_data; - ab3100_devs[i].pdata_size = sizeof(struct ab3100_platform_data); - } - - err = mfd_add_devices(&client->dev, 0, ab3100_devs, - ARRAY_SIZE(ab3100_devs), NULL, 0); - - ab3100_setup_debugfs(ab3100); - - return 0; - - exit_no_ops: - exit_no_irq: - exit_no_setup: - i2c_unregister_device(ab3100->testreg_client); - exit_no_testreg_client: - exit_no_detect: - kfree(ab3100); - return err; -} - -static int __devexit ab3100_remove(struct i2c_client *client) -{ - struct ab3100 *ab3100 = i2c_get_clientdata(client); - - /* Unregister subdevices */ - mfd_remove_devices(&client->dev); - - ab3100_remove_debugfs(); - i2c_unregister_device(ab3100->testreg_client); - - /* - * At this point, all subscribers should have unregistered - * their notifiers so deactivate IRQ - */ - free_irq(client->irq, ab3100); - kfree(ab3100); - return 0; -} - -static const struct i2c_device_id ab3100_id[] = { - { "ab3100", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ab3100_id); - -static struct i2c_driver ab3100_driver = { - .driver = { - .name = "ab3100", - .owner = THIS_MODULE, - }, - .id_table = ab3100_id, - .probe = ab3100_probe, - .remove = __devexit_p(ab3100_remove), -}; - -static int __init ab3100_i2c_init(void) -{ - return i2c_add_driver(&ab3100_driver); -} - -static void __exit ab3100_i2c_exit(void) -{ - i2c_del_driver(&ab3100_driver); -} - -subsys_initcall(ab3100_i2c_init); -module_exit(ab3100_i2c_exit); - -MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); -MODULE_DESCRIPTION("AB3100 core driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab3100-otp.c b/ANDROID_3.4.5/drivers/mfd/ab3100-otp.c deleted file mode 100644 index 8440010e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab3100-otp.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * drivers/mfd/ab3100_otp.c - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Driver to read out OTP from the AB3100 Mixed-signal circuit - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mfd/abx500.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> - -/* The OTP registers */ -#define AB3100_OTP0 0xb0 -#define AB3100_OTP1 0xb1 -#define AB3100_OTP2 0xb2 -#define AB3100_OTP3 0xb3 -#define AB3100_OTP4 0xb4 -#define AB3100_OTP5 0xb5 -#define AB3100_OTP6 0xb6 -#define AB3100_OTP7 0xb7 -#define AB3100_OTPP 0xbf - -/** - * struct ab3100_otp - * @dev containing device - * @locked whether the OTP is locked, after locking, no more bits - * can be changed but before locking it is still possible - * to change bits from 1->0. - * @freq clocking frequency for the OTP, this frequency is either - * 32768Hz or 1MHz/30 - * @paf product activation flag, indicates whether this is a real - * product (paf true) or a lab board etc (paf false) - * @imeich if this is set it is possible to override the - * IMEI number found in the tac, fac and svn fields with - * (secured) software - * @cid customer ID - * @tac type allocation code of the IMEI - * @fac final assembly code of the IMEI - * @svn software version number of the IMEI - * @debugfs a debugfs file used when dumping to file - */ -struct ab3100_otp { - struct device *dev; - bool locked; - u32 freq; - bool paf; - bool imeich; - u16 cid:14; - u32 tac:20; - u8 fac; - u32 svn:20; - struct dentry *debugfs; -}; - -static int __init ab3100_otp_read(struct ab3100_otp *otp) -{ - u8 otpval[8]; - u8 otpp; - int err; - - err = abx500_get_register_interruptible(otp->dev, 0, - AB3100_OTPP, &otpp); - if (err) { - dev_err(otp->dev, "unable to read OTPP register\n"); - return err; - } - - err = abx500_get_register_page_interruptible(otp->dev, 0, - AB3100_OTP0, otpval, 8); - if (err) { - dev_err(otp->dev, "unable to read OTP register page\n"); - return err; - } - - /* Cache OTP properties, they never change by nature */ - otp->locked = (otpp & 0x80); - otp->freq = (otpp & 0x40) ? 32768 : 34100; - otp->paf = (otpval[1] & 0x80); - otp->imeich = (otpval[1] & 0x40); - otp->cid = ((otpval[1] << 8) | otpval[0]) & 0x3fff; - otp->tac = ((otpval[4] & 0x0f) << 16) | (otpval[3] << 8) | otpval[2]; - otp->fac = ((otpval[5] & 0x0f) << 4) | (otpval[4] >> 4); - otp->svn = (otpval[7] << 12) | (otpval[6] << 4) | (otpval[5] >> 4); - return 0; -} - -/* - * This is a simple debugfs human-readable file that dumps out - * the contents of the OTP. - */ -#ifdef CONFIG_DEBUG_FS -static int ab3100_show_otp(struct seq_file *s, void *v) -{ - struct ab3100_otp *otp = s->private; - - seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED"); - seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq); - seq_printf(s, "PAF is %s\n", otp->paf ? "SET" : "NOT SET"); - seq_printf(s, "IMEI is %s\n", otp->imeich ? - "CHANGEABLE" : "NOT CHANGEABLE"); - seq_printf(s, "CID: 0x%04x (decimal: %d)\n", otp->cid, otp->cid); - seq_printf(s, "IMEI: %u-%u-%u\n", otp->tac, otp->fac, otp->svn); - return 0; -} - -static int ab3100_otp_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab3100_show_otp, inode->i_private); -} - -static const struct file_operations ab3100_otp_operations = { - .open = ab3100_otp_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init ab3100_otp_init_debugfs(struct device *dev, - struct ab3100_otp *otp) -{ - otp->debugfs = debugfs_create_file("ab3100_otp", S_IFREG | S_IRUGO, - NULL, otp, - &ab3100_otp_operations); - if (!otp->debugfs) { - dev_err(dev, "AB3100 debugfs OTP file registration failed!\n"); - return -ENOENT; - } - return 0; -} - -static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) -{ - debugfs_remove(otp->debugfs); -} -#else -/* Compile this out if debugfs not selected */ -static inline int __init ab3100_otp_init_debugfs(struct device *dev, - struct ab3100_otp *otp) -{ - return 0; -} - -static inline void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) -{ -} -#endif - -#define SHOW_AB3100_ATTR(name) \ -static ssize_t ab3100_otp_##name##_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{\ - struct ab3100_otp *otp = dev_get_drvdata(dev); \ - return sprintf(buf, "%u\n", otp->name); \ -} - -SHOW_AB3100_ATTR(locked) -SHOW_AB3100_ATTR(freq) -SHOW_AB3100_ATTR(paf) -SHOW_AB3100_ATTR(imeich) -SHOW_AB3100_ATTR(cid) -SHOW_AB3100_ATTR(fac) -SHOW_AB3100_ATTR(tac) -SHOW_AB3100_ATTR(svn) - -static struct device_attribute ab3100_otp_attrs[] = { - __ATTR(locked, S_IRUGO, ab3100_otp_locked_show, NULL), - __ATTR(freq, S_IRUGO, ab3100_otp_freq_show, NULL), - __ATTR(paf, S_IRUGO, ab3100_otp_paf_show, NULL), - __ATTR(imeich, S_IRUGO, ab3100_otp_imeich_show, NULL), - __ATTR(cid, S_IRUGO, ab3100_otp_cid_show, NULL), - __ATTR(fac, S_IRUGO, ab3100_otp_fac_show, NULL), - __ATTR(tac, S_IRUGO, ab3100_otp_tac_show, NULL), - __ATTR(svn, S_IRUGO, ab3100_otp_svn_show, NULL), -}; - -static int __init ab3100_otp_probe(struct platform_device *pdev) -{ - struct ab3100_otp *otp; - int err = 0; - int i; - - otp = kzalloc(sizeof(struct ab3100_otp), GFP_KERNEL); - if (!otp) { - dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n"); - return -ENOMEM; - } - otp->dev = &pdev->dev; - - /* Replace platform data coming in with a local struct */ - platform_set_drvdata(pdev, otp); - - err = ab3100_otp_read(otp); - if (err) - goto err_otp_read; - - dev_info(&pdev->dev, "AB3100 OTP readout registered\n"); - - /* sysfs entries */ - for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++) { - err = device_create_file(&pdev->dev, - &ab3100_otp_attrs[i]); - if (err) - goto err_create_file; - } - - /* debugfs entries */ - err = ab3100_otp_init_debugfs(&pdev->dev, otp); - if (err) - goto err_init_debugfs; - - return 0; - -err_init_debugfs: -err_create_file: - while (--i >= 0) - device_remove_file(&pdev->dev, &ab3100_otp_attrs[i]); -err_otp_read: - kfree(otp); - return err; -} - -static int __exit ab3100_otp_remove(struct platform_device *pdev) -{ - struct ab3100_otp *otp = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++) - device_remove_file(&pdev->dev, - &ab3100_otp_attrs[i]); - ab3100_otp_exit_debugfs(otp); - kfree(otp); - return 0; -} - -static struct platform_driver ab3100_otp_driver = { - .driver = { - .name = "ab3100-otp", - .owner = THIS_MODULE, - }, - .remove = __exit_p(ab3100_otp_remove), -}; - -static int __init ab3100_otp_init(void) -{ - return platform_driver_probe(&ab3100_otp_driver, - ab3100_otp_probe); -} - -static void __exit ab3100_otp_exit(void) -{ - platform_driver_unregister(&ab3100_otp_driver); -} - -module_init(ab3100_otp_init); -module_exit(ab3100_otp_exit); - -MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); -MODULE_DESCRIPTION("AB3100 OTP Readout Driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab5500-core.c b/ANDROID_3.4.5/drivers/mfd/ab5500-core.c deleted file mode 100644 index 54d0fe40..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab5500-core.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * Copyright (C) 2007-2011 ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - * Low-level core for exclusive access to the AB5500 IC on the I2C bus - * and some basic chip-configuration. - * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> - * Author: Mattias Wallin <mattias.wallin@stericsson.com> - * Author: Rickard Andersson <rickard.andersson@stericsson.com> - * Author: Karl Komierowski <karl.komierowski@stericsson.com> - * Author: Bibek Basu <bibek.basu@stericsson.com> - * - * TODO: Event handling with irq_chip. Waiting for PRCMU fw support. - */ - -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/err.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/random.h> -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab5500.h> -#include <linux/list.h> -#include <linux/bitops.h> -#include <linux/spinlock.h> -#include <linux/mfd/core.h> -#include <linux/mfd/db5500-prcmu.h> - -#include "ab5500-core.h" -#include "ab5500-debugfs.h" - -#define AB5500_NUM_EVENT_REG 23 -#define AB5500_IT_LATCH0_REG 0x40 -#define AB5500_IT_MASK0_REG 0x60 - -/* - * Permissible register ranges for reading and writing per device and bank. - * - * The ranges must be listed in increasing address order, and no overlaps are - * allowed. It is assumed that write permission implies read permission - * (i.e. only RO and RW permissions should be used). Ranges with write - * permission must not be split up. - */ - -#define NO_RANGE {.count = 0, .range = NULL,} -static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = { - [AB5500_DEVID_USB] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_ADC] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_LEDS] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .bankid = AB5500_BANK_LED, - .nranges = 1, - .range = (struct ab5500_reg_range[]) { - { - .first = 0x00, - .last = 0x0C, - .perm = AB5500_PERM_RW, - }, - }, - }, - }, - }, - [AB5500_DEVID_VIDEO] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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, - }, - }, - }, - }, - }, - [AB5500_DEVID_REGULATORS] = { - .nbanks = 2, - .bank = (struct ab5500_i2c_ranges []) { - { - .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, - }, - }, - }, - { - .bankid = AB5500_BANK_SIM_USBSIM, - .nranges = 1, - .range = (struct ab5500_reg_range[]) { - { - .first = 0x13, - .last = 0x19, - .perm = AB5500_PERM_RW, - }, - }, - }, - }, - }, - [AB5500_DEVID_SIM] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .bankid = AB5500_BANK_SIM_USBSIM, - .nranges = 1, - .range = (struct ab5500_reg_range[]) { - { - .first = 0x13, - .last = 0x19, - .perm = AB5500_PERM_RW, - }, - }, - }, - }, - }, - [AB5500_DEVID_RTC] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_CHARGER] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_FUELGAUGE] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_VIBRATOR] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_CODEC] = { - .nbanks = 1, - .bank = (struct ab5500_i2c_ranges []) { - { - .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_DEVID_POWER] = { - .nbanks = 2, - .bank = (struct ab5500_i2c_ranges []) { - { - .bankid = AB5500_BANK_STARTUP, - .nranges = 1, - .range = (struct ab5500_reg_range[]) { - { - .first = 0x30, - .last = 0x30, - .perm = AB5500_PERM_RW, - }, - }, - }, - { - .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, - .nranges = 1, - .range = (struct ab5500_reg_range[]) { - { - .first = 0x01, - .last = 0x01, - .perm = AB5500_PERM_RW, - }, - }, - }, - }, - }, -}; - -#define AB5500_IRQ(bank, bit) ((bank) * 8 + (bit)) - -/* I appologize for the resource names beeing a mix of upper case - * and lower case but I want them to be exact as the documentation */ -static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = { - [AB5500_DEVID_LEDS] = { - .name = "ab5500-leds", - .id = AB5500_DEVID_LEDS, - }, - [AB5500_DEVID_POWER] = { - .name = "ab5500-power", - .id = AB5500_DEVID_POWER, - }, - [AB5500_DEVID_REGULATORS] = { - .name = "ab5500-regulator", - .id = AB5500_DEVID_REGULATORS, - }, - [AB5500_DEVID_SIM] = { - .name = "ab5500-sim", - .id = AB5500_DEVID_SIM, - .num_resources = 1, - .resources = (struct resource[]) { - { - .name = "SIMOFF", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(2, 0), /*rising*/ - .end = AB5500_IRQ(2, 1), /*falling*/ - }, - }, - }, - [AB5500_DEVID_RTC] = { - .name = "ab5500-rtc", - .id = AB5500_DEVID_RTC, - .num_resources = 1, - .resources = (struct resource[]) { - { - .name = "RTC_Alarm", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(1, 7), - .end = AB5500_IRQ(1, 7), - } - }, - }, - [AB5500_DEVID_CHARGER] = { - .name = "ab5500-charger", - .id = AB5500_DEVID_CHARGER, - }, - [AB5500_DEVID_ADC] = { - .name = "ab5500-adc", - .id = AB5500_DEVID_ADC, - .num_resources = 10, - .resources = (struct resource[]) { - { - .name = "TRIGGER-0", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 0), - .end = AB5500_IRQ(0, 0), - }, - { - .name = "TRIGGER-1", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 1), - .end = AB5500_IRQ(0, 1), - }, - { - .name = "TRIGGER-2", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 2), - .end = AB5500_IRQ(0, 2), - }, - { - .name = "TRIGGER-3", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 3), - .end = AB5500_IRQ(0, 3), - }, - { - .name = "TRIGGER-4", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 4), - .end = AB5500_IRQ(0, 4), - }, - { - .name = "TRIGGER-5", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 5), - .end = AB5500_IRQ(0, 5), - }, - { - .name = "TRIGGER-6", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 6), - .end = AB5500_IRQ(0, 6), - }, - { - .name = "TRIGGER-7", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 7), - .end = AB5500_IRQ(0, 7), - }, - { - .name = "TRIGGER-VBAT", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 8), - .end = AB5500_IRQ(0, 8), - }, - { - .name = "TRIGGER-VBAT-TXON", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(0, 9), - .end = AB5500_IRQ(0, 9), - }, - }, - }, - [AB5500_DEVID_FUELGAUGE] = { - .name = "ab5500-fuelgauge", - .id = AB5500_DEVID_FUELGAUGE, - .num_resources = 6, - .resources = (struct resource[]) { - { - .name = "Batt_attach", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(7, 5), - .end = AB5500_IRQ(7, 5), - }, - { - .name = "Batt_removal", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(7, 6), - .end = AB5500_IRQ(7, 6), - }, - { - .name = "UART_framing", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(7, 7), - .end = AB5500_IRQ(7, 7), - }, - { - .name = "UART_overrun", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 0), - .end = AB5500_IRQ(8, 0), - }, - { - .name = "UART_Rdy_RX", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 1), - .end = AB5500_IRQ(8, 1), - }, - { - .name = "UART_Rdy_TX", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 2), - .end = AB5500_IRQ(8, 2), - }, - }, - }, - [AB5500_DEVID_VIBRATOR] = { - .name = "ab5500-vibrator", - .id = AB5500_DEVID_VIBRATOR, - }, - [AB5500_DEVID_CODEC] = { - .name = "ab5500-codec", - .id = AB5500_DEVID_CODEC, - .num_resources = 3, - .resources = (struct resource[]) { - { - .name = "audio_spkr1_ovc", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 5), - .end = AB5500_IRQ(9, 5), - }, - { - .name = "audio_plllocked", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 6), - .end = AB5500_IRQ(9, 6), - }, - { - .name = "audio_spkr2_ovc", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(17, 4), - .end = AB5500_IRQ(17, 4), - }, - }, - }, - [AB5500_DEVID_USB] = { - .name = "ab5500-usb", - .id = AB5500_DEVID_USB, - .num_resources = 36, - .resources = (struct resource[]) { - { - .name = "Link_Update", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(22, 1), - .end = AB5500_IRQ(22, 1), - }, - { - .name = "DCIO", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 3), - .end = AB5500_IRQ(8, 4), - }, - { - .name = "VBUS_R", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 5), - .end = AB5500_IRQ(8, 5), - }, - { - .name = "VBUS_F", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 6), - .end = AB5500_IRQ(8, 6), - }, - { - .name = "CHGstate_10_PCVBUSchg", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(8, 7), - .end = AB5500_IRQ(8, 7), - }, - { - .name = "DCIOreverse_ovc", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 0), - .end = AB5500_IRQ(9, 0), - }, - { - .name = "USBCharDetDone", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 1), - .end = AB5500_IRQ(9, 1), - }, - { - .name = "DCIO_no_limit", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 2), - .end = AB5500_IRQ(9, 2), - }, - { - .name = "USB_suspend", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 3), - .end = AB5500_IRQ(9, 3), - }, - { - .name = "DCIOreverse_fwdcurrent", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 4), - .end = AB5500_IRQ(9, 4), - }, - { - .name = "Vbus_Imeasmax_change", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(9, 5), - .end = AB5500_IRQ(9, 6), - }, - { - .name = "OVV", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 5), - .end = AB5500_IRQ(14, 5), - }, - { - .name = "USBcharging_NOTok", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 3), - .end = AB5500_IRQ(15, 3), - }, - { - .name = "usb_adp_sensoroff", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 6), - .end = AB5500_IRQ(15, 6), - }, - { - .name = "usb_adp_probeplug", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 7), - .end = AB5500_IRQ(15, 7), - }, - { - .name = "usb_adp_sinkerror", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 0), - .end = AB5500_IRQ(16, 6), - }, - { - .name = "usb_adp_sourceerror", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 1), - .end = AB5500_IRQ(16, 1), - }, - { - .name = "usb_idgnd_r", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 2), - .end = AB5500_IRQ(16, 2), - }, - { - .name = "usb_idgnd_f", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 3), - .end = AB5500_IRQ(16, 3), - }, - { - .name = "usb_iddetR1", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 4), - .end = AB5500_IRQ(16, 5), - }, - { - .name = "usb_iddetR2", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(16, 6), - .end = AB5500_IRQ(16, 7), - }, - { - .name = "usb_iddetR3", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(17, 0), - .end = AB5500_IRQ(17, 1), - }, - { - .name = "usb_iddetR4", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(17, 2), - .end = AB5500_IRQ(17, 3), - }, - { - .name = "CharTempWindowOk", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(17, 7), - .end = AB5500_IRQ(18, 0), - }, - { - .name = "USB_SprDetect", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(18, 1), - .end = AB5500_IRQ(18, 1), - }, - { - .name = "usb_adp_probe_unplug", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(18, 2), - .end = AB5500_IRQ(18, 2), - }, - { - .name = "VBUSChDrop", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(18, 3), - .end = AB5500_IRQ(18, 4), - }, - { - .name = "dcio_char_rec_done", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(18, 5), - .end = AB5500_IRQ(18, 5), - }, - { - .name = "Charging_stopped_by_temp", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(18, 6), - .end = AB5500_IRQ(18, 6), - }, - { - .name = "CHGstate_11_SafeModeVBUS", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 1), - .end = AB5500_IRQ(21, 2), - }, - { - .name = "CHGstate_12_comletedVBUS", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 2), - .end = AB5500_IRQ(21, 2), - }, - { - .name = "CHGstate_13_completedVBUS", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 3), - .end = AB5500_IRQ(21, 3), - }, - { - .name = "CHGstate_14_FullChgDCIO", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 4), - .end = AB5500_IRQ(21, 4), - }, - { - .name = "CHGstate_15_SafeModeDCIO", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 5), - .end = AB5500_IRQ(21, 5), - }, - { - .name = "CHGstate_16_OFFsuspendDCIO", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 6), - .end = AB5500_IRQ(21, 6), - }, - { - .name = "CHGstate_17_completedDCIO", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(21, 7), - .end = AB5500_IRQ(21, 7), - }, - }, - }, - [AB5500_DEVID_OTP] = { - .name = "ab5500-otp", - .id = AB5500_DEVID_OTP, - }, - [AB5500_DEVID_VIDEO] = { - .name = "ab5500-video", - .id = AB5500_DEVID_VIDEO, - .num_resources = 1, - .resources = (struct resource[]) { - { - .name = "plugTVdet", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(22, 2), - .end = AB5500_IRQ(22, 2), - }, - }, - }, - [AB5500_DEVID_DBIECI] = { - .name = "ab5500-dbieci", - .id = AB5500_DEVID_DBIECI, - .num_resources = 10, - .resources = (struct resource[]) { - { - .name = "COLL", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 0), - .end = AB5500_IRQ(14, 0), - }, - { - .name = "RESERR", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 1), - .end = AB5500_IRQ(14, 1), - }, - { - .name = "FRAERR", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 2), - .end = AB5500_IRQ(14, 2), - }, - { - .name = "COMERR", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 3), - .end = AB5500_IRQ(14, 3), - }, - { - .name = "BSI_indicator", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 4), - .end = AB5500_IRQ(14, 4), - }, - { - .name = "SPDSET", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 6), - .end = AB5500_IRQ(14, 6), - }, - { - .name = "DSENT", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(14, 7), - .end = AB5500_IRQ(14, 7), - }, - { - .name = "DREC", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 0), - .end = AB5500_IRQ(15, 0), - }, - { - .name = "ACCINT", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 1), - .end = AB5500_IRQ(15, 1), - }, - { - .name = "NOPINT", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(15, 2), - .end = AB5500_IRQ(15, 2), - }, - }, - }, - [AB5500_DEVID_ONSWA] = { - .name = "ab5500-onswa", - .id = AB5500_DEVID_ONSWA, - .num_resources = 2, - .resources = (struct resource[]) { - { - .name = "ONSWAn_rising", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(1, 3), - .end = AB5500_IRQ(1, 3), - }, - { - .name = "ONSWAn_falling", - .flags = IORESOURCE_IRQ, - .start = AB5500_IRQ(1, 4), - .end = AB5500_IRQ(1, 4), - }, - }, - }, -}; - -/* - * Functionality for getting/setting register values. - */ -int ab5500_get_register_interruptible_raw(struct ab5500 *ab, - u8 bank, u8 reg, - u8 *value) -{ - int err; - - if (bank >= AB5500_NUM_BANKS) - return -EINVAL; - - err = mutex_lock_interruptible(&ab->access_mutex); - if (err) - return err; - err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1); - - mutex_unlock(&ab->access_mutex); - return err; -} - -static int get_register_page_interruptible(struct ab5500 *ab, u8 bank, - u8 first_reg, u8 *regvals, u8 numregs) -{ - int err; - - if (bank >= AB5500_NUM_BANKS) - return -EINVAL; - - err = mutex_lock_interruptible(&ab->access_mutex); - if (err) - return err; - - while (numregs) { - /* The hardware limit for get page is 4 */ - u8 curnum = min_t(u8, numregs, 4u); - - err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, - first_reg, regvals, curnum); - if (err) - goto out; - - numregs -= curnum; - first_reg += curnum; - regvals += curnum; - } - -out: - mutex_unlock(&ab->access_mutex); - return err; -} - -int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, - u8 reg, u8 bitmask, u8 bitvalues) -{ - int err = 0; - - if (bank >= AB5500_NUM_BANKS) - return -EINVAL; - - if (bitmask) { - u8 buf; - - err = mutex_lock_interruptible(&ab->access_mutex); - if (err) - return err; - - if (bitmask == 0xFF) /* No need to read in this case. */ - buf = bitvalues; - else { /* Read and modify the register value. */ - err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, - reg, &buf, 1); - if (err) - return err; - - buf = ((~bitmask & buf) | (bitmask & bitvalues)); - } - /* Write the new value. */ - err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg, - &buf, 1); - - mutex_unlock(&ab->access_mutex); - } - return err; -} - -static int -set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value) -{ - return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, - 0xff, value); -} - -/* - * Read/write permission checking functions. - */ -static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank) -{ - u8 i; - - if (devid < AB5500_NUM_DEVICES) { - for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) { - if (ab5500_bank_ranges[devid].bank[i].bankid == bank) - return &ab5500_bank_ranges[devid].bank[i]; - } - } - return NULL; -} - -static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) -{ - u8 i; /* range loop index */ - const struct ab5500_i2c_ranges *bankref; - - bankref = get_bankref(devid, bank); - if (bankref == NULL || last_reg < first_reg) - return false; - - for (i = 0; i < bankref->nranges; i++) { - if (first_reg < bankref->range[i].first) - break; - if ((last_reg <= bankref->range[i].last) && - (bankref->range[i].perm & AB5500_PERM_WR)) - return true; - } - return false; -} - -static bool reg_write_allowed(u8 devid, u8 bank, u8 reg) -{ - return page_write_allowed(devid, bank, reg, reg); -} - -static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) -{ - u8 i; - const struct ab5500_i2c_ranges *bankref; - - bankref = get_bankref(devid, bank); - if (bankref == NULL || last_reg < first_reg) - return false; - - - /* Find the range (if it exists in the list) that includes first_reg. */ - for (i = 0; i < bankref->nranges; i++) { - if (first_reg < bankref->range[i].first) - return false; - if (first_reg <= bankref->range[i].last) - break; - } - /* Make sure that the entire range up to and including last_reg is - * readable. This may span several of the ranges in the list. - */ - while ((i < bankref->nranges) && - (bankref->range[i].perm & AB5500_PERM_RD)) { - if (last_reg <= bankref->range[i].last) - return true; - if ((++i >= bankref->nranges) || - (bankref->range[i].first != - (bankref->range[i - 1].last + 1))) { - break; - } - } - return false; -} - -static bool reg_read_allowed(u8 devid, u8 bank, u8 reg) -{ - return page_read_allowed(devid, bank, reg, reg); -} - - -/* - * The exported register access functionality. - */ -static int ab5500_get_chip_id(struct device *dev) -{ - struct ab5500 *ab = dev_get_drvdata(dev->parent); - - return (int)ab->chip_id; -} - -static int ab5500_mask_and_set_register_interruptible(struct device *dev, - u8 bank, u8 reg, u8 bitmask, u8 bitvalues) -{ - struct ab5500 *ab; - struct platform_device *pdev = to_platform_device(dev); - - if ((AB5500_NUM_BANKS <= bank) || - !reg_write_allowed(pdev->id, bank, reg)) - return -EINVAL; - - ab = dev_get_drvdata(dev->parent); - return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, - bitmask, bitvalues); -} - -static int ab5500_set_register_interruptible(struct device *dev, u8 bank, - u8 reg, u8 value) -{ - return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, - value); -} - -static int ab5500_get_register_interruptible(struct device *dev, u8 bank, - u8 reg, u8 *value) -{ - struct ab5500 *ab; - struct platform_device *pdev = to_platform_device(dev); - - if ((AB5500_NUM_BANKS <= bank) || - !reg_read_allowed(pdev->id, bank, reg)) - return -EINVAL; - - ab = dev_get_drvdata(dev->parent); - return ab5500_get_register_interruptible_raw(ab, bank, reg, value); -} - -static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank, - u8 first_reg, u8 *regvals, u8 numregs) -{ - struct ab5500 *ab; - struct platform_device *pdev = to_platform_device(dev); - - if ((AB5500_NUM_BANKS <= bank) || - !page_read_allowed(pdev->id, bank, - first_reg, (first_reg + numregs - 1))) - return -EINVAL; - - ab = dev_get_drvdata(dev->parent); - return get_register_page_interruptible(ab, bank, first_reg, regvals, - numregs); -} - -static int -ab5500_event_registers_startup_state_get(struct device *dev, u8 *event) -{ - struct ab5500 *ab; - - ab = dev_get_drvdata(dev->parent); - if (!ab->startup_events_read) - return -EAGAIN; /* Try again later */ - - memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG); - return 0; -} - -static struct abx500_ops ab5500_ops = { - .get_chip_id = ab5500_get_chip_id, - .get_register = ab5500_get_register_interruptible, - .set_register = ab5500_set_register_interruptible, - .get_register_page = ab5500_get_register_page_interruptible, - .set_register_page = NULL, - .mask_and_set_register = ab5500_mask_and_set_register_interruptible, - .event_registers_startup_state_get = - ab5500_event_registers_startup_state_get, - .startup_irq_enabled = NULL, -}; - -/* - * ab5500_setup : Basic set-up, datastructure creation/destruction - * and I2C interface.This sets up a default config - * in the AB5500 chip so that it will work as expected. - * @ab : Pointer to ab5500 structure - * @settings : Pointer to struct abx500_init_settings - * @size : Size of init data - */ -static int __init ab5500_setup(struct ab5500 *ab, - struct abx500_init_settings *settings, unsigned int size) -{ - int err = 0; - int i; - - for (i = 0; i < size; i++) { - err = ab5500_mask_and_set_register_interruptible_raw(ab, - settings[i].bank, - settings[i].reg, - 0xFF, settings[i].setting); - if (err) - goto exit_no_setup; - - /* If event mask register update the event mask in ab5500 */ - if ((settings[i].bank == AB5500_BANK_IT) && - (AB5500_MASK_BASE <= settings[i].reg) && - (settings[i].reg <= AB5500_MASK_END)) { - ab->mask[settings[i].reg - AB5500_MASK_BASE] = - settings[i].setting; - } - } -exit_no_setup: - return err; -} - -struct ab_family_id { - u8 id; - char *name; -}; - -static const struct ab_family_id ids[] __initdata = { - /* AB5500 */ - { - .id = AB5500_1_0, - .name = "1.0" - }, - { - .id = AB5500_1_1, - .name = "1.1" - }, - /* Terminator */ - { - .id = 0x00, - } -}; - -static int __init ab5500_probe(struct platform_device *pdev) -{ - struct ab5500 *ab; - struct ab5500_platform_data *ab5500_plf_data = - pdev->dev.platform_data; - int err; - int i; - - ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL); - if (!ab) { - dev_err(&pdev->dev, - "could not allocate ab5500 device\n"); - return -ENOMEM; - } - - /* Initialize data structure */ - mutex_init(&ab->access_mutex); - mutex_init(&ab->irq_lock); - ab->dev = &pdev->dev; - - platform_set_drvdata(pdev, ab); - - /* Read chip ID register */ - err = ab5500_get_register_interruptible_raw(ab, - AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, - AB5500_CHIP_ID, &ab->chip_id); - if (err) { - dev_err(&pdev->dev, "could not communicate with the analog " - "baseband chip\n"); - goto exit_no_detect; - } - - for (i = 0; ids[i].id != 0x0; i++) { - if (ids[i].id == ab->chip_id) { - snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, - "AB5500 %s", ids[i].name); - break; - } - } - if (ids[i].id == 0x0) { - dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n", - ab->chip_id); - dev_err(&pdev->dev, "driver not started!\n"); - goto exit_no_detect; - } - - /* Clear and mask all interrupts */ - for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) { - u8 latchreg = AB5500_IT_LATCH0_REG + i; - u8 maskreg = AB5500_IT_MASK0_REG + i; - u8 val; - - ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT, - latchreg, &val); - set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff); - ab->mask[i] = ab->oldmask[i] = 0xff; - } - - err = abx500_register_ops(&pdev->dev, &ab5500_ops); - if (err) { - dev_err(&pdev->dev, "ab5500_register ops error\n"); - goto exit_no_detect; - } - - /* Set up and register the platform devices. */ - for (i = 0; i < AB5500_NUM_DEVICES; i++) { - ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i]; - ab5500_devs[i].pdata_size = - sizeof(ab5500_plf_data->dev_data[i]); - } - - err = mfd_add_devices(&pdev->dev, 0, ab5500_devs, - ARRAY_SIZE(ab5500_devs), NULL, - ab5500_plf_data->irq.base); - if (err) { - dev_err(&pdev->dev, "ab5500_mfd_add_device error\n"); - goto exit_no_detect; - } - - err = ab5500_setup(ab, ab5500_plf_data->init_settings, - ab5500_plf_data->init_settings_sz); - if (err) { - dev_err(&pdev->dev, "ab5500_setup error\n"); - goto exit_no_detect; - } - - ab5500_setup_debugfs(ab); - - dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]); - return 0; - -exit_no_detect: - kfree(ab); - return err; -} - -static int __exit ab5500_remove(struct platform_device *pdev) -{ - struct ab5500 *ab = platform_get_drvdata(pdev); - - ab5500_remove_debugfs(); - mfd_remove_devices(&pdev->dev); - kfree(ab); - return 0; -} - -static struct platform_driver ab5500_driver = { - .driver = { - .name = "ab5500-core", - .owner = THIS_MODULE, - }, - .remove = __exit_p(ab5500_remove), -}; - -static int __init ab5500_core_init(void) -{ - return platform_driver_probe(&ab5500_driver, ab5500_probe); -} - -static void __exit ab5500_core_exit(void) -{ - platform_driver_unregister(&ab5500_driver); -} - -subsys_initcall(ab5500_core_init); -module_exit(ab5500_core_exit); - -MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); -MODULE_DESCRIPTION("AB5500 core driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab5500-core.h b/ANDROID_3.4.5/drivers/mfd/ab5500-core.h deleted file mode 100644 index 63b30b17..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab5500-core.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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); diff --git a/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.c b/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.c deleted file mode 100644 index 72006940..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (C) 2011 ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - * Debugfs support for the AB5500 MFD driver - */ - -#include <linux/module.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab5500.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); -} diff --git a/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.h b/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.h deleted file mode 100644 index 7330a9b6..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab5500-debugfs.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 diff --git a/ANDROID_3.4.5/drivers/mfd/ab8500-core.c b/ANDROID_3.4.5/drivers/mfd/ab8500-core.c deleted file mode 100644 index 1f08704f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab8500-core.c +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> - * Author: Rabin Vincent <rabin.vincent@stericsson.com> - * Author: Mattias Wallin <mattias.wallin@stericsson.com> - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mfd/core.h> -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab8500.h> -#include <linux/regulator/ab8500.h> - -/* - * Interrupt register offsets - * Bank : 0x0E - */ -#define AB8500_IT_SOURCE1_REG 0x00 -#define AB8500_IT_SOURCE2_REG 0x01 -#define AB8500_IT_SOURCE3_REG 0x02 -#define AB8500_IT_SOURCE4_REG 0x03 -#define AB8500_IT_SOURCE5_REG 0x04 -#define AB8500_IT_SOURCE6_REG 0x05 -#define AB8500_IT_SOURCE7_REG 0x06 -#define AB8500_IT_SOURCE8_REG 0x07 -#define AB9540_IT_SOURCE13_REG 0x0C -#define AB8500_IT_SOURCE19_REG 0x12 -#define AB8500_IT_SOURCE20_REG 0x13 -#define AB8500_IT_SOURCE21_REG 0x14 -#define AB8500_IT_SOURCE22_REG 0x15 -#define AB8500_IT_SOURCE23_REG 0x16 -#define AB8500_IT_SOURCE24_REG 0x17 - -/* - * latch registers - */ -#define AB8500_IT_LATCH1_REG 0x20 -#define AB8500_IT_LATCH2_REG 0x21 -#define AB8500_IT_LATCH3_REG 0x22 -#define AB8500_IT_LATCH4_REG 0x23 -#define AB8500_IT_LATCH5_REG 0x24 -#define AB8500_IT_LATCH6_REG 0x25 -#define AB8500_IT_LATCH7_REG 0x26 -#define AB8500_IT_LATCH8_REG 0x27 -#define AB8500_IT_LATCH9_REG 0x28 -#define AB8500_IT_LATCH10_REG 0x29 -#define AB8500_IT_LATCH12_REG 0x2B -#define AB9540_IT_LATCH13_REG 0x2C -#define AB8500_IT_LATCH19_REG 0x32 -#define AB8500_IT_LATCH20_REG 0x33 -#define AB8500_IT_LATCH21_REG 0x34 -#define AB8500_IT_LATCH22_REG 0x35 -#define AB8500_IT_LATCH23_REG 0x36 -#define AB8500_IT_LATCH24_REG 0x37 - -/* - * mask registers - */ - -#define AB8500_IT_MASK1_REG 0x40 -#define AB8500_IT_MASK2_REG 0x41 -#define AB8500_IT_MASK3_REG 0x42 -#define AB8500_IT_MASK4_REG 0x43 -#define AB8500_IT_MASK5_REG 0x44 -#define AB8500_IT_MASK6_REG 0x45 -#define AB8500_IT_MASK7_REG 0x46 -#define AB8500_IT_MASK8_REG 0x47 -#define AB8500_IT_MASK9_REG 0x48 -#define AB8500_IT_MASK10_REG 0x49 -#define AB8500_IT_MASK11_REG 0x4A -#define AB8500_IT_MASK12_REG 0x4B -#define AB8500_IT_MASK13_REG 0x4C -#define AB8500_IT_MASK14_REG 0x4D -#define AB8500_IT_MASK15_REG 0x4E -#define AB8500_IT_MASK16_REG 0x4F -#define AB8500_IT_MASK17_REG 0x50 -#define AB8500_IT_MASK18_REG 0x51 -#define AB8500_IT_MASK19_REG 0x52 -#define AB8500_IT_MASK20_REG 0x53 -#define AB8500_IT_MASK21_REG 0x54 -#define AB8500_IT_MASK22_REG 0x55 -#define AB8500_IT_MASK23_REG 0x56 -#define AB8500_IT_MASK24_REG 0x57 - -#define AB8500_REV_REG 0x80 -#define AB8500_IC_NAME_REG 0x82 -#define AB8500_SWITCH_OFF_STATUS 0x00 - -#define AB8500_TURN_ON_STATUS 0x00 - -#define AB9540_MODEM_CTRL2_REG 0x23 -#define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2) - -/* - * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt - * numbers are indexed into this array with (num / 8). The interupts are - * defined in linux/mfd/ab8500.h - * - * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at - * offset 0. - */ -/* AB8500 support */ -static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, -}; - -/* AB9540 support */ -static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, -}; - -static const char ab8500_version_str[][7] = { - [AB8500_VERSION_AB8500] = "AB8500", - [AB8500_VERSION_AB8505] = "AB8505", - [AB8500_VERSION_AB9540] = "AB9540", - [AB8500_VERSION_AB8540] = "AB8540", -}; - -static int ab8500_get_chip_id(struct device *dev) -{ - struct ab8500 *ab8500; - - if (!dev) - return -EINVAL; - ab8500 = dev_get_drvdata(dev->parent); - return ab8500 ? (int)ab8500->chip_id : -EINVAL; -} - -static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, - u8 reg, u8 data) -{ - int ret; - /* - * Put the u8 bank and u8 register together into a an u16. - * The bank on higher 8 bits and register in lower 8 bits. - * */ - u16 addr = ((u16)bank) << 8 | reg; - - dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); - - mutex_lock(&ab8500->lock); - - ret = ab8500->write(ab8500, addr, data); - if (ret < 0) - dev_err(ab8500->dev, "failed to write reg %#x: %d\n", - addr, ret); - mutex_unlock(&ab8500->lock); - - return ret; -} - -static int ab8500_set_register(struct device *dev, u8 bank, - u8 reg, u8 value) -{ - struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); - - return set_register_interruptible(ab8500, bank, reg, value); -} - -static int get_register_interruptible(struct ab8500 *ab8500, u8 bank, - u8 reg, u8 *value) -{ - int ret; - /* put the u8 bank and u8 reg together into a an u16. - * bank on higher 8 bits and reg in lower */ - u16 addr = ((u16)bank) << 8 | reg; - - mutex_lock(&ab8500->lock); - - ret = ab8500->read(ab8500, addr); - if (ret < 0) - dev_err(ab8500->dev, "failed to read reg %#x: %d\n", - addr, ret); - else - *value = ret; - - mutex_unlock(&ab8500->lock); - dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret); - - return ret; -} - -static int ab8500_get_register(struct device *dev, u8 bank, - u8 reg, u8 *value) -{ - struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); - - return get_register_interruptible(ab8500, bank, reg, value); -} - -static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank, - u8 reg, u8 bitmask, u8 bitvalues) -{ - int ret; - /* put the u8 bank and u8 reg together into a an u16. - * bank on higher 8 bits and reg in lower */ - u16 addr = ((u16)bank) << 8 | reg; - - mutex_lock(&ab8500->lock); - - if (ab8500->write_masked == NULL) { - u8 data; - - ret = ab8500->read(ab8500, addr); - if (ret < 0) { - dev_err(ab8500->dev, "failed to read reg %#x: %d\n", - addr, ret); - goto out; - } - - data = (u8)ret; - data = (~bitmask & data) | (bitmask & bitvalues); - - ret = ab8500->write(ab8500, addr, data); - if (ret < 0) - dev_err(ab8500->dev, "failed to write reg %#x: %d\n", - addr, ret); - - dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, - data); - goto out; - } - ret = ab8500->write_masked(ab8500, addr, bitmask, bitvalues); - if (ret < 0) - dev_err(ab8500->dev, "failed to modify reg %#x: %d\n", addr, - ret); -out: - mutex_unlock(&ab8500->lock); - return ret; -} - -static int ab8500_mask_and_set_register(struct device *dev, - u8 bank, u8 reg, u8 bitmask, u8 bitvalues) -{ - struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); - - return mask_and_set_register_interruptible(ab8500, bank, reg, - bitmask, bitvalues); - -} - -static struct abx500_ops ab8500_ops = { - .get_chip_id = ab8500_get_chip_id, - .get_register = ab8500_get_register, - .set_register = ab8500_set_register, - .get_register_page = NULL, - .set_register_page = NULL, - .mask_and_set_register = ab8500_mask_and_set_register, - .event_registers_startup_state_get = NULL, - .startup_irq_enabled = NULL, -}; - -static void ab8500_irq_lock(struct irq_data *data) -{ - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - - mutex_lock(&ab8500->irq_lock); -} - -static void ab8500_irq_sync_unlock(struct irq_data *data) -{ - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ab8500->mask_size; i++) { - u8 old = ab8500->oldmask[i]; - u8 new = ab8500->mask[i]; - int reg; - - if (new == old) - continue; - - /* - * Interrupt register 12 doesn't exist prior to AB8500 version - * 2.0 - */ - if (ab8500->irq_reg_offset[i] == 11 && - is_ab8500_1p1_or_earlier(ab8500)) - continue; - - ab8500->oldmask[i] = new; - - reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i]; - set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new); - } - - mutex_unlock(&ab8500->irq_lock); -} - -static void ab8500_irq_mask(struct irq_data *data) -{ - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - int offset = data->irq - ab8500->irq_base; - int index = offset / 8; - int mask = 1 << (offset % 8); - - ab8500->mask[index] |= mask; -} - -static void ab8500_irq_unmask(struct irq_data *data) -{ - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - int offset = data->irq - ab8500->irq_base; - int index = offset / 8; - int mask = 1 << (offset % 8); - - ab8500->mask[index] &= ~mask; -} - -static struct irq_chip ab8500_irq_chip = { - .name = "ab8500", - .irq_bus_lock = ab8500_irq_lock, - .irq_bus_sync_unlock = ab8500_irq_sync_unlock, - .irq_mask = ab8500_irq_mask, - .irq_disable = ab8500_irq_mask, - .irq_unmask = ab8500_irq_unmask, -}; - -static irqreturn_t ab8500_irq(int irq, void *dev) -{ - struct ab8500 *ab8500 = dev; - int i; - - dev_vdbg(ab8500->dev, "interrupt\n"); - - for (i = 0; i < ab8500->mask_size; i++) { - int regoffset = ab8500->irq_reg_offset[i]; - int status; - u8 value; - - /* - * Interrupt register 12 doesn't exist prior to AB8500 version - * 2.0 - */ - if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500)) - continue; - - status = get_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_LATCH1_REG + regoffset, &value); - if (status < 0 || value == 0) - continue; - - do { - int bit = __ffs(value); - int line = i * 8 + bit; - - handle_nested_irq(ab8500->irq_base + line); - value &= ~(1 << bit); - } while (value); - } - - return IRQ_HANDLED; -} - -static int ab8500_irq_init(struct ab8500 *ab8500) -{ - int base = ab8500->irq_base; - int irq; - int num_irqs; - - if (is_ab9540(ab8500)) - num_irqs = AB9540_NR_IRQS; - else if (is_ab8505(ab8500)) - num_irqs = AB8505_NR_IRQS; - else - num_irqs = AB8500_NR_IRQS; - - for (irq = base; irq < base + num_irqs; irq++) { - irq_set_chip_data(irq, ab8500); - irq_set_chip_and_handler(irq, &ab8500_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - } - - return 0; -} - -static void ab8500_irq_remove(struct ab8500 *ab8500) -{ - int base = ab8500->irq_base; - int irq; - int num_irqs; - - if (is_ab9540(ab8500)) - num_irqs = AB9540_NR_IRQS; - else if (is_ab8505(ab8500)) - num_irqs = AB8505_NR_IRQS; - else - num_irqs = AB8500_NR_IRQS; - - for (irq = base; irq < base + num_irqs; irq++) { -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); - } -} - -/* AB8500 GPIO Resources */ -static struct resource __devinitdata ab8500_gpio_resources[] = { - { - .name = "GPIO_INT6", - .start = AB8500_INT_GPIO6R, - .end = AB8500_INT_GPIO41F, - .flags = IORESOURCE_IRQ, - } -}; - -/* AB9540 GPIO Resources */ -static struct resource __devinitdata ab9540_gpio_resources[] = { - { - .name = "GPIO_INT6", - .start = AB8500_INT_GPIO6R, - .end = AB8500_INT_GPIO41F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "GPIO_INT14", - .start = AB9540_INT_GPIO50R, - .end = AB9540_INT_GPIO54R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "GPIO_INT15", - .start = AB9540_INT_GPIO50F, - .end = AB9540_INT_GPIO54F, - .flags = IORESOURCE_IRQ, - } -}; - -static struct resource __devinitdata ab8500_gpadc_resources[] = { - { - .name = "HW_CONV_END", - .start = AB8500_INT_GP_HW_ADC_CONV_END, - .end = AB8500_INT_GP_HW_ADC_CONV_END, - .flags = IORESOURCE_IRQ, - }, - { - .name = "SW_CONV_END", - .start = AB8500_INT_GP_SW_ADC_CONV_END, - .end = AB8500_INT_GP_SW_ADC_CONV_END, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_rtc_resources[] = { - { - .name = "60S", - .start = AB8500_INT_RTC_60S, - .end = AB8500_INT_RTC_60S, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ALARM", - .start = AB8500_INT_RTC_ALARM, - .end = AB8500_INT_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_poweronkey_db_resources[] = { - { - .name = "ONKEY_DBF", - .start = AB8500_INT_PON_KEY1DB_F, - .end = AB8500_INT_PON_KEY1DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ONKEY_DBR", - .start = AB8500_INT_PON_KEY1DB_R, - .end = AB8500_INT_PON_KEY1DB_R, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_av_acc_detect_resources[] = { - { - .name = "ACC_DETECT_1DB_F", - .start = AB8500_INT_ACC_DETECT_1DB_F, - .end = AB8500_INT_ACC_DETECT_1DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_1DB_R", - .start = AB8500_INT_ACC_DETECT_1DB_R, - .end = AB8500_INT_ACC_DETECT_1DB_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_21DB_F", - .start = AB8500_INT_ACC_DETECT_21DB_F, - .end = AB8500_INT_ACC_DETECT_21DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_21DB_R", - .start = AB8500_INT_ACC_DETECT_21DB_R, - .end = AB8500_INT_ACC_DETECT_21DB_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_22DB_F", - .start = AB8500_INT_ACC_DETECT_22DB_F, - .end = AB8500_INT_ACC_DETECT_22DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_22DB_R", - .start = AB8500_INT_ACC_DETECT_22DB_R, - .end = AB8500_INT_ACC_DETECT_22DB_R, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_charger_resources[] = { - { - .name = "MAIN_CH_UNPLUG_DET", - .start = AB8500_INT_MAIN_CH_UNPLUG_DET, - .end = AB8500_INT_MAIN_CH_UNPLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CHARGE_PLUG_DET", - .start = AB8500_INT_MAIN_CH_PLUG_DET, - .end = AB8500_INT_MAIN_CH_PLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_LINK_STATUS", - .start = AB8500_INT_USB_LINK_STATUS, - .end = AB8500_INT_USB_LINK_STATUS, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_OVV", - .start = AB8500_INT_VBUS_OVV, - .end = AB8500_INT_VBUS_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CH_TH_PROT_R", - .start = AB8500_INT_USB_CH_TH_PROT_R, - .end = AB8500_INT_USB_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CH_TH_PROT_F", - .start = AB8500_INT_USB_CH_TH_PROT_F, - .end = AB8500_INT_USB_CH_TH_PROT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_EXT_CH_NOT_OK", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_TH_PROT_R", - .start = AB8500_INT_MAIN_CH_TH_PROT_R, - .end = AB8500_INT_MAIN_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_TH_PROT_F", - .start = AB8500_INT_MAIN_CH_TH_PROT_F, - .end = AB8500_INT_MAIN_CH_TH_PROT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CHARGER_NOT_OKR", - .start = AB8500_INT_USB_CHARGER_NOT_OKR, - .end = AB8500_INT_USB_CHARGER_NOT_OKR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CH_WD_EXP", - .start = AB8500_INT_CH_WD_EXP, - .end = AB8500_INT_CH_WD_EXP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_btemp_resources[] = { - { - .name = "BAT_CTRL_INDB", - .start = AB8500_INT_BAT_CTRL_INDB, - .end = AB8500_INT_BAT_CTRL_INDB, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_LOW", - .start = AB8500_INT_BTEMP_LOW, - .end = AB8500_INT_BTEMP_LOW, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_HIGH", - .start = AB8500_INT_BTEMP_HIGH, - .end = AB8500_INT_BTEMP_HIGH, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_LOW_MEDIUM", - .start = AB8500_INT_BTEMP_LOW_MEDIUM, - .end = AB8500_INT_BTEMP_LOW_MEDIUM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_MEDIUM_HIGH", - .start = AB8500_INT_BTEMP_MEDIUM_HIGH, - .end = AB8500_INT_BTEMP_MEDIUM_HIGH, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_fg_resources[] = { - { - .name = "NCONV_ACCU", - .start = AB8500_INT_CCN_CONV_ACC, - .end = AB8500_INT_CCN_CONV_ACC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT_OVV", - .start = AB8500_INT_BATT_OVV, - .end = AB8500_INT_BATT_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_F", - .start = AB8500_INT_LOW_BAT_F, - .end = AB8500_INT_LOW_BAT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_R", - .start = AB8500_INT_LOW_BAT_R, - .end = AB8500_INT_LOW_BAT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CC_INT_CALIB", - .start = AB8500_INT_CC_INT_CALIB, - .end = AB8500_INT_CC_INT_CALIB, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CCEOC", - .start = AB8500_INT_CCEOC, - .end = AB8500_INT_CCEOC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_chargalg_resources[] = {}; - -#ifdef CONFIG_DEBUG_FS -static struct resource __devinitdata ab8500_debug_resources[] = { - { - .name = "IRQ_FIRST", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "IRQ_LAST", - .start = AB8500_INT_XTAL32K_KO, - .end = AB8500_INT_XTAL32K_KO, - .flags = IORESOURCE_IRQ, - }, -}; -#endif - -static struct resource __devinitdata ab8500_usb_resources[] = { - { - .name = "ID_WAKEUP_R", - .start = AB8500_INT_ID_WAKEUP_R, - .end = AB8500_INT_ID_WAKEUP_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_WAKEUP_F", - .start = AB8500_INT_ID_WAKEUP_F, - .end = AB8500_INT_ID_WAKEUP_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_LINK_STATUS", - .start = AB8500_INT_USB_LINK_STATUS, - .end = AB8500_INT_USB_LINK_STATUS, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_ADP_PROBE_PLUG", - .start = AB8500_INT_ADP_PROBE_PLUG, - .end = AB8500_INT_ADP_PROBE_PLUG, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_ADP_PROBE_UNPLUG", - .start = AB8500_INT_ADP_PROBE_UNPLUG, - .end = AB8500_INT_ADP_PROBE_UNPLUG, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata ab8500_temp_resources[] = { - { - .name = "AB8500_TEMP_WARM", - .start = AB8500_INT_TEMP_WARM, - .end = AB8500_INT_TEMP_WARM, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell __devinitdata abx500_common_devs[] = { -#ifdef CONFIG_DEBUG_FS - { - .name = "ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, - }, -#endif - { - .name = "ab8500-sysctrl", - }, - { - .name = "ab8500-regulator", - }, - { - .name = "ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), - .resources = ab8500_gpadc_resources, - }, - { - .name = "ab8500-rtc", - .num_resources = ARRAY_SIZE(ab8500_rtc_resources), - .resources = ab8500_rtc_resources, - }, - { - .name = "ab8500-charger", - .num_resources = ARRAY_SIZE(ab8500_charger_resources), - .resources = ab8500_charger_resources, - }, - { - .name = "ab8500-btemp", - .num_resources = ARRAY_SIZE(ab8500_btemp_resources), - .resources = ab8500_btemp_resources, - }, - { - .name = "ab8500-fg", - .num_resources = ARRAY_SIZE(ab8500_fg_resources), - .resources = ab8500_fg_resources, - }, - { - .name = "ab8500-chargalg", - .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), - .resources = ab8500_chargalg_resources, - }, - { - .name = "ab8500-acc-det", - .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), - .resources = ab8500_av_acc_detect_resources, - }, - { - .name = "ab8500-codec", - }, - - { - .name = "ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, - }, - { - .name = "ab8500-pwm", - .id = 1, - }, - { - .name = "ab8500-pwm", - .id = 2, - }, - { - .name = "ab8500-pwm", - .id = 3, - }, - { .name = "ab8500-leds", }, - { - .name = "ab8500-denc", - }, - { - .name = "ab8500-temp", - .num_resources = ARRAY_SIZE(ab8500_temp_resources), - .resources = ab8500_temp_resources, - }, -}; - -static struct mfd_cell __devinitdata ab8500_devs[] = { - { - .name = "ab8500-gpio", - .num_resources = ARRAY_SIZE(ab8500_gpio_resources), - .resources = ab8500_gpio_resources, - }, - { - .name = "ab8500-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, - }, -}; - -static struct mfd_cell __devinitdata ab9540_devs[] = { - { - .name = "ab8500-gpio", - .num_resources = ARRAY_SIZE(ab9540_gpio_resources), - .resources = ab9540_gpio_resources, - }, - { - .name = "ab9540-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, - }, -}; - -static ssize_t show_chip_id(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ab8500 *ab8500; - - ab8500 = dev_get_drvdata(dev); - return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); -} - -/* - * ab8500 has switched off due to (SWITCH_OFF_STATUS): - * 0x01 Swoff bit programming - * 0x02 Thermal protection activation - * 0x04 Vbat lower then BattOk falling threshold - * 0x08 Watchdog expired - * 0x10 Non presence of 32kHz clock - * 0x20 Battery level lower than power on reset threshold - * 0x40 Power on key 1 pressed longer than 10 seconds - * 0x80 DB8500 thermal shutdown - */ -static ssize_t show_switch_off_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_RTC, - AB8500_SWITCH_OFF_STATUS, &value); - if (ret < 0) - return ret; - 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 ssize_t show_ab9540_dbbrstn(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ab8500 *ab8500; - int ret; - u8 value; - - ab8500 = dev_get_drvdata(dev); - - ret = get_register_interruptible(ab8500, AB8500_REGU_CTRL2, - AB9540_MODEM_CTRL2_REG, &value); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", - (value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0); -} - -static ssize_t store_ab9540_dbbrstn(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct ab8500 *ab8500; - int ret = count; - int err; - u8 bitvalues; - - ab8500 = dev_get_drvdata(dev); - - if (count > 0) { - switch (buf[0]) { - case '0': - bitvalues = 0; - break; - case '1': - bitvalues = AB9540_MODEM_CTRL2_SWDBBRSTN_BIT; - break; - default: - goto exit; - } - - err = mask_and_set_register_interruptible(ab8500, - AB8500_REGU_CTRL2, AB9540_MODEM_CTRL2_REG, - AB9540_MODEM_CTRL2_SWDBBRSTN_BIT, bitvalues); - if (err) - dev_info(ab8500->dev, - "Failed to set DBBRSTN %c, err %#x\n", - buf[0], err); - } - -exit: - return ret; -} - -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(turn_on_status, S_IRUGO, show_turn_on_status, NULL); -static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR, - show_ab9540_dbbrstn, store_ab9540_dbbrstn); - -static struct attribute *ab8500_sysfs_entries[] = { - &dev_attr_chip_id.attr, - &dev_attr_switch_off_status.attr, - &dev_attr_turn_on_status.attr, - NULL, -}; - -static struct attribute *ab9540_sysfs_entries[] = { - &dev_attr_chip_id.attr, - &dev_attr_switch_off_status.attr, - &dev_attr_turn_on_status.attr, - &dev_attr_dbbrstn.attr, - NULL, -}; - -static struct attribute_group ab8500_attr_group = { - .attrs = ab8500_sysfs_entries, -}; - -static struct attribute_group ab9540_attr_group = { - .attrs = ab9540_sysfs_entries, -}; - -int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) -{ - struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); - int ret; - int i; - u8 value; - - if (plat) - ab8500->irq_base = plat->irq_base; - - mutex_init(&ab8500->lock); - mutex_init(&ab8500->irq_lock); - - if (version != AB8500_VERSION_UNDEFINED) - ab8500->version = version; - else { - ret = get_register_interruptible(ab8500, AB8500_MISC, - AB8500_IC_NAME_REG, &value); - if (ret < 0) - return ret; - - ab8500->version = value; - } - - ret = get_register_interruptible(ab8500, AB8500_MISC, - AB8500_REV_REG, &value); - if (ret < 0) - return ret; - - ab8500->chip_id = value; - - dev_info(ab8500->dev, "detected chip, %s rev. %1x.%1x\n", - ab8500_version_str[ab8500->version], - ab8500->chip_id >> 4, - ab8500->chip_id & 0x0F); - - /* Configure AB8500 or AB9540 IRQ */ - if (is_ab9540(ab8500) || is_ab8505(ab8500)) { - ab8500->mask_size = AB9540_NUM_IRQ_REGS; - ab8500->irq_reg_offset = ab9540_irq_regoffset; - } else { - ab8500->mask_size = AB8500_NUM_IRQ_REGS; - ab8500->irq_reg_offset = ab8500_irq_regoffset; - } - ab8500->mask = kzalloc(ab8500->mask_size, GFP_KERNEL); - if (!ab8500->mask) - return -ENOMEM; - ab8500->oldmask = kzalloc(ab8500->mask_size, GFP_KERNEL); - if (!ab8500->oldmask) { - ret = -ENOMEM; - goto out_freemask; - } - /* - * ab8500 has switched off due to (SWITCH_OFF_STATUS): - * 0x01 Swoff bit programming - * 0x02 Thermal protection activation - * 0x04 Vbat lower then BattOk falling threshold - * 0x08 Watchdog expired - * 0x10 Non presence of 32kHz clock - * 0x20 Battery level lower than power on reset threshold - * 0x40 Power on key 1 pressed longer than 10 seconds - * 0x80 DB8500 thermal shutdown - */ - - ret = get_register_interruptible(ab8500, AB8500_RTC, - AB8500_SWITCH_OFF_STATUS, &value); - if (ret < 0) - return ret; - dev_info(ab8500->dev, "switch off status: %#x", value); - - if (plat && plat->init) - plat->init(ab8500); - - /* Clear and mask all interrupts */ - for (i = 0; i < ab8500->mask_size; i++) { - /* - * Interrupt register 12 doesn't exist prior to AB8500 version - * 2.0 - */ - if (ab8500->irq_reg_offset[i] == 11 && - is_ab8500_1p1_or_earlier(ab8500)) - continue; - - get_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_LATCH1_REG + ab8500->irq_reg_offset[i], - &value); - set_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i], 0xff); - } - - ret = abx500_register_ops(ab8500->dev, &ab8500_ops); - if (ret) - goto out_freeoldmask; - - for (i = 0; i < ab8500->mask_size; i++) - ab8500->mask[i] = ab8500->oldmask[i] = 0xff; - - if (ab8500->irq_base) { - ret = ab8500_irq_init(ab8500); - if (ret) - goto out_freeoldmask; - - ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - "ab8500", ab8500); - if (ret) - goto out_removeirq; - } - - ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, - ARRAY_SIZE(abx500_common_devs), NULL, - ab8500->irq_base); - - if (ret) - goto out_freeirq; - - if (is_ab9540(ab8500)) - ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, - ARRAY_SIZE(ab9540_devs), NULL, - ab8500->irq_base); - else - ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, - ARRAY_SIZE(ab9540_devs), NULL, - ab8500->irq_base); - if (ret) - goto out_freeirq; - - if (is_ab9540(ab8500)) - ret = sysfs_create_group(&ab8500->dev->kobj, - &ab9540_attr_group); - else - ret = sysfs_create_group(&ab8500->dev->kobj, - &ab8500_attr_group); - if (ret) - dev_err(ab8500->dev, "error creating sysfs entries\n"); - else - return ret; - -out_freeirq: - if (ab8500->irq_base) - free_irq(ab8500->irq, ab8500); -out_removeirq: - if (ab8500->irq_base) - ab8500_irq_remove(ab8500); -out_freeoldmask: - kfree(ab8500->oldmask); -out_freemask: - kfree(ab8500->mask); - - return ret; -} - -int __devexit ab8500_exit(struct ab8500 *ab8500) -{ - if (is_ab9540(ab8500)) - sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group); - else - sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); - mfd_remove_devices(ab8500->dev); - if (ab8500->irq_base) { - free_irq(ab8500->irq, ab8500); - ab8500_irq_remove(ab8500); - } - kfree(ab8500->oldmask); - kfree(ab8500->mask); - - return 0; -} - -MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent"); -MODULE_DESCRIPTION("AB8500 MFD core"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab8500-debugfs.c b/ANDROID_3.4.5/drivers/mfd/ab8500-debugfs.c deleted file mode 100644 index 9a0211aa..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab8500-debugfs.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson. - * License Terms: GNU General Public License v2 - */ - -#include <linux/seq_file.h> -#include <linux/uaccess.h> -#include <linux/fs.h> -#include <linux/module.h> -#include <linux/debugfs.h> -#include <linux/platform_device.h> - -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab8500.h> - -static u32 debug_bank; -static u32 debug_address; - -/** - * struct ab8500_reg_range - * @first: the first address of the range - * @last: the last address of the range - * @perm: access permissions for the range - */ -struct ab8500_reg_range { - u8 first; - u8 last; - u8 perm; -}; - -/** - * struct ab8500_i2c_ranges - * @num_ranges: the number of ranges in the list - * @bankid: bank identifier - * @range: the list of register ranges - */ -struct ab8500_i2c_ranges { - u8 num_ranges; - u8 bankid; - const struct ab8500_reg_range *range; -}; - -#define AB8500_NAME_STRING "ab8500" -#define AB8500_NUM_BANKS 22 - -#define AB8500_REV_REG 0x80 - -static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { - [0x0] = { - .num_ranges = 0, - .range = 0, - }, - [AB8500_SYS_CTRL1_BLOCK] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x02, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_SYS_CTRL2_BLOCK] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0D, - }, - { - .first = 0x0F, - .last = 0x17, - }, - { - .first = 0x30, - .last = 0x30, - }, - { - .first = 0x32, - .last = 0x33, - }, - }, - }, - [AB8500_REGU_CTRL1] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x03, - .last = 0x10, - }, - { - .first = 0x80, - .last = 0x84, - }, - }, - }, - [AB8500_REGU_CTRL2] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x15, - }, - { - .first = 0x17, - .last = 0x19, - }, - { - .first = 0x1B, - .last = 0x1D, - }, - { - .first = 0x1F, - .last = 0x22, - }, - { - .first = 0x40, - .last = 0x44, - }, - /* 0x80-0x8B is SIM registers and should - * not be accessed from here */ - }, - }, - [AB8500_USB] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x87, - .last = 0x8A, - }, - }, - }, - [AB8500_TVOUT] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x12, - }, - { - .first = 0x15, - .last = 0x17, - }, - { - .first = 0x19, - .last = 0x21, - }, - { - .first = 0x27, - .last = 0x2C, - }, - { - .first = 0x41, - .last = 0x41, - }, - { - .first = 0x45, - .last = 0x5B, - }, - { - .first = 0x5D, - .last = 0x5D, - }, - { - .first = 0x69, - .last = 0x69, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_DBI] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_ECI_AV_ACC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [0x9] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_GPADC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x08, - }, - }, - }, - [AB8500_CHARGER] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x03, - }, - { - .first = 0x05, - .last = 0x05, - }, - { - .first = 0x40, - .last = 0x40, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x44, - .last = 0x44, - }, - { - .first = 0x50, - .last = 0x55, - }, - { - .first = 0x80, - .last = 0x82, - }, - { - .first = 0xC0, - .last = 0xC2, - }, - }, - }, - [AB8500_GAS_GAUGE] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x07, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_AUDIO] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x6F, - }, - }, - }, - [AB8500_INTERRUPT] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_RTC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0F, - }, - }, - }, - [AB8500_MISC] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x05, - }, - { - .first = 0x10, - .last = 0x15, - }, - { - .first = 0x20, - .last = 0x25, - }, - { - .first = 0x30, - .last = 0x35, - }, - { - .first = 0x40, - .last = 0x45, - }, - { - .first = 0x50, - .last = 0x50, - }, - { - .first = 0x60, - .last = 0x67, - }, - { - .first = 0x80, - .last = 0x80, - }, - }, - }, - [0x11] = { - .num_ranges = 0, - .range = NULL, - }, - [0x12] = { - .num_ranges = 0, - .range = NULL, - }, - [0x13] = { - .num_ranges = 0, - .range = NULL, - }, - [0x14] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_OTP_EMUL] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x01, - .last = 0x0F, - }, - }, - }, -}; - -static int ab8500_registers_print(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - unsigned int i; - u32 bank = debug_bank; - - seq_printf(s, AB8500_NAME_STRING " register values:\n"); - - seq_printf(s, " bank %u:\n", bank); - for (i = 0; i < debug_ranges[bank].num_ranges; i++) { - u32 reg; - - for (reg = debug_ranges[bank].range[i].first; - reg <= debug_ranges[bank].range[i].last; - reg++) { - u8 value; - int err; - - err = abx500_get_register_interruptible(dev, - (u8)bank, (u8)reg, &value); - if (err < 0) { - dev_err(dev, "ab->read fail %d\n", err); - return err; - } - - err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, - reg, value); - if (err < 0) { - dev_err(dev, "seq_printf overflow\n"); - /* Error is not returned here since - * the output is wanted in any case */ - return 0; - } - } - } - return 0; -} - -static int ab8500_registers_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_registers_print, inode->i_private); -} - -static const struct file_operations ab8500_registers_fops = { - .open = ab8500_registers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static int ab8500_bank_print(struct seq_file *s, void *p) -{ - return seq_printf(s, "%d\n", debug_bank); -} - -static int ab8500_bank_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_bank_print, inode->i_private); -} - -static ssize_t ab8500_bank_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_bank; - int err; - - /* Get userspace string and assure termination */ - err = kstrtoul_from_user(user_buf, count, 0, &user_bank); - if (err) - return err; - - if (user_bank >= AB8500_NUM_BANKS) { - dev_err(dev, "debugfs error input > number of banks\n"); - return -EINVAL; - } - - debug_bank = user_bank; - - return count; -} - -static int ab8500_address_print(struct seq_file *s, void *p) -{ - return seq_printf(s, "0x%02X\n", debug_address); -} - -static int ab8500_address_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_address_print, inode->i_private); -} - -static ssize_t ab8500_address_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_address; - int err; - - /* Get userspace string and assure termination */ - err = kstrtoul_from_user(user_buf, count, 0, &user_address); - if (err) - return err; - - if (user_address > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - debug_address = user_address; - return count; -} - -static int ab8500_val_print(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - int ret; - u8 regvalue; - - ret = abx500_get_register_interruptible(dev, - (u8)debug_bank, (u8)debug_address, ®value); - if (ret < 0) { - dev_err(dev, "abx500_get_reg fail %d, %d\n", - ret, __LINE__); - return -EINVAL; - } - seq_printf(s, "0x%02X\n", regvalue); - - return 0; -} - -static int ab8500_val_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_val_print, inode->i_private); -} - -static ssize_t ab8500_val_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_val; - int err; - - /* Get userspace string and assure termination */ - err = kstrtoul_from_user(user_buf, count, 0, &user_val); - if (err) - return err; - - if (user_val > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - err = abx500_set_register_interruptible(dev, - (u8)debug_bank, debug_address, (u8)user_val); - if (err < 0) { - printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); - return -EINVAL; - } - - return count; -} - -static const struct file_operations ab8500_bank_fops = { - .open = ab8500_bank_open, - .write = ab8500_bank_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_address_fops = { - .open = ab8500_address_open, - .write = ab8500_address_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_val_fops = { - .open = ab8500_val_open, - .write = ab8500_val_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static struct dentry *ab8500_dir; -static struct dentry *ab8500_reg_file; -static struct dentry *ab8500_bank_file; -static struct dentry *ab8500_address_file; -static struct dentry *ab8500_val_file; - -static int __devinit ab8500_debug_probe(struct platform_device *plf) -{ - debug_bank = AB8500_MISC; - debug_address = AB8500_REV_REG & 0x00FF; - - ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); - if (!ab8500_dir) - goto exit_no_debugfs; - - ab8500_reg_file = debugfs_create_file("all-bank-registers", - S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); - if (!ab8500_reg_file) - goto exit_destroy_dir; - - ab8500_bank_file = debugfs_create_file("register-bank", - (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops); - if (!ab8500_bank_file) - goto exit_destroy_reg; - - ab8500_address_file = debugfs_create_file("register-address", - (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, - &ab8500_address_fops); - if (!ab8500_address_file) - goto exit_destroy_bank; - - ab8500_val_file = debugfs_create_file("register-value", - (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops); - if (!ab8500_val_file) - goto exit_destroy_address; - - return 0; - -exit_destroy_address: - debugfs_remove(ab8500_address_file); -exit_destroy_bank: - debugfs_remove(ab8500_bank_file); -exit_destroy_reg: - debugfs_remove(ab8500_reg_file); -exit_destroy_dir: - debugfs_remove(ab8500_dir); -exit_no_debugfs: - dev_err(&plf->dev, "failed to create debugfs entries.\n"); - return -ENOMEM; -} - -static int __devexit ab8500_debug_remove(struct platform_device *plf) -{ - debugfs_remove(ab8500_val_file); - debugfs_remove(ab8500_address_file); - debugfs_remove(ab8500_bank_file); - debugfs_remove(ab8500_reg_file); - debugfs_remove(ab8500_dir); - - return 0; -} - -static struct platform_driver ab8500_debug_driver = { - .driver = { - .name = "ab8500-debug", - .owner = THIS_MODULE, - }, - .probe = ab8500_debug_probe, - .remove = __devexit_p(ab8500_debug_remove) -}; - -static int __init ab8500_debug_init(void) -{ - return platform_driver_register(&ab8500_debug_driver); -} - -static void __exit ab8500_debug_exit(void) -{ - platform_driver_unregister(&ab8500_debug_driver); -} -subsys_initcall(ab8500_debug_init); -module_exit(ab8500_debug_exit); - -MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com"); -MODULE_DESCRIPTION("AB8500 DEBUG"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab8500-gpadc.c b/ANDROID_3.4.5/drivers/mfd/ab8500-gpadc.c deleted file mode 100644 index c39fc716..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab8500-gpadc.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Arun R Murthy <arun.murthy@stericsson.com> - * Author: Daniel Willerud <daniel.willerud@stericsson.com> - * Author: Johan Palsson <johan.palsson@stericsson.com> - */ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/completion.h> -#include <linux/regulator/consumer.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab8500.h> -#include <linux/mfd/abx500/ab8500-gpadc.h> - -/* - * GPADC register offsets - * Bank : 0x0A - */ -#define AB8500_GPADC_CTRL1_REG 0x00 -#define AB8500_GPADC_CTRL2_REG 0x01 -#define AB8500_GPADC_CTRL3_REG 0x02 -#define AB8500_GPADC_AUTO_TIMER_REG 0x03 -#define AB8500_GPADC_STAT_REG 0x04 -#define AB8500_GPADC_MANDATAL_REG 0x05 -#define AB8500_GPADC_MANDATAH_REG 0x06 -#define AB8500_GPADC_AUTODATAL_REG 0x07 -#define AB8500_GPADC_AUTODATAH_REG 0x08 -#define AB8500_GPADC_MUX_CTRL_REG 0x09 - -/* - * OTP register offsets - * Bank : 0x15 - */ -#define AB8500_GPADC_CAL_1 0x0F -#define AB8500_GPADC_CAL_2 0x10 -#define AB8500_GPADC_CAL_3 0x11 -#define AB8500_GPADC_CAL_4 0x12 -#define AB8500_GPADC_CAL_5 0x13 -#define AB8500_GPADC_CAL_6 0x14 -#define AB8500_GPADC_CAL_7 0x15 - -/* gpadc constants */ -#define EN_VINTCORE12 0x04 -#define EN_VTVOUT 0x02 -#define EN_GPADC 0x01 -#define DIS_GPADC 0x00 -#define SW_AVG_16 0x60 -#define ADC_SW_CONV 0x04 -#define EN_ICHAR 0x80 -#define BTEMP_PULL_UP 0x08 -#define EN_BUF 0x40 -#define DIS_ZERO 0x00 -#define GPADC_BUSY 0x01 - -/* GPADC constants from AB8500 spec, UM0836 */ -#define ADC_RESOLUTION 1024 -#define ADC_CH_BTEMP_MIN 0 -#define ADC_CH_BTEMP_MAX 1350 -#define ADC_CH_DIETEMP_MIN 0 -#define ADC_CH_DIETEMP_MAX 1350 -#define ADC_CH_CHG_V_MIN 0 -#define ADC_CH_CHG_V_MAX 20030 -#define ADC_CH_ACCDET2_MIN 0 -#define ADC_CH_ACCDET2_MAX 2500 -#define ADC_CH_VBAT_MIN 2300 -#define ADC_CH_VBAT_MAX 4800 -#define ADC_CH_CHG_I_MIN 0 -#define ADC_CH_CHG_I_MAX 1500 -#define ADC_CH_BKBAT_MIN 0 -#define ADC_CH_BKBAT_MAX 3200 - -/* This is used to not lose precision when dividing to get gain and offset */ -#define CALIB_SCALE 1000 - -enum cal_channels { - ADC_INPUT_VMAIN = 0, - ADC_INPUT_BTEMP, - ADC_INPUT_VBAT, - NBR_CAL_INPUTS, -}; - -/** - * struct adc_cal_data - Table for storing gain and offset for the calibrated - * ADC channels - * @gain: Gain of the ADC channel - * @offset: Offset of the ADC channel - */ -struct adc_cal_data { - u64 gain; - u64 offset; -}; - -/** - * struct ab8500_gpadc - AB8500 GPADC device information - * @chip_id ABB chip id - * @dev: pointer to the struct device - * @node: a list of AB8500 GPADCs, hence prepared for - reentrance - * @ab8500_gpadc_complete: pointer to the struct completion, to indicate - * the completion of gpadc conversion - * @ab8500_gpadc_lock: structure of type mutex - * @regu: pointer to the struct regulator - * @irq: interrupt number that is used by gpadc - * @cal_data array of ADC calibration data structs - */ -struct ab8500_gpadc { - u8 chip_id; - struct device *dev; - struct list_head node; - struct completion ab8500_gpadc_complete; - struct mutex ab8500_gpadc_lock; - struct regulator *regu; - int irq; - struct adc_cal_data cal_data[NBR_CAL_INPUTS]; -}; - -static LIST_HEAD(ab8500_gpadc_list); - -/** - * ab8500_gpadc_get() - returns a reference to the primary AB8500 GPADC - * (i.e. the first GPADC in the instance list) - */ -struct ab8500_gpadc *ab8500_gpadc_get(char *name) -{ - struct ab8500_gpadc *gpadc; - - list_for_each_entry(gpadc, &ab8500_gpadc_list, node) { - if (!strcmp(name, dev_name(gpadc->dev))) - return gpadc; - } - - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(ab8500_gpadc_get); - -/** - * 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 res; - - switch (channel) { - case MAIN_CHARGER_V: - /* For some reason we don't have calibrated data */ - if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) { - res = ADC_CH_CHG_V_MIN + (ADC_CH_CHG_V_MAX - - ADC_CH_CHG_V_MIN) * ad_value / - ADC_RESOLUTION; - break; - } - /* Here we can use the calibrated data */ - res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VMAIN].gain + - gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE; - break; - - case BAT_CTRL: - case BTEMP_BALL: - case ACC_DETECT1: - case ADC_AUX1: - case ADC_AUX2: - /* For some reason we don't have calibrated data */ - if (!gpadc->cal_data[ADC_INPUT_BTEMP].gain) { - res = ADC_CH_BTEMP_MIN + (ADC_CH_BTEMP_MAX - - ADC_CH_BTEMP_MIN) * ad_value / - ADC_RESOLUTION; - break; - } - /* Here we can use the calibrated data */ - res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_BTEMP].gain + - gpadc->cal_data[ADC_INPUT_BTEMP].offset) / CALIB_SCALE; - break; - - case MAIN_BAT_V: - /* For some reason we don't have calibrated data */ - if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) { - res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX - - ADC_CH_VBAT_MIN) * ad_value / - ADC_RESOLUTION; - break; - } - /* Here we can use the calibrated data */ - res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VBAT].gain + - gpadc->cal_data[ADC_INPUT_VBAT].offset) / CALIB_SCALE; - break; - - case DIE_TEMP: - res = ADC_CH_DIETEMP_MIN + - (ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN) * ad_value / - ADC_RESOLUTION; - break; - - case ACC_DETECT2: - res = ADC_CH_ACCDET2_MIN + - (ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN) * ad_value / - ADC_RESOLUTION; - break; - - case VBUS_V: - res = ADC_CH_CHG_V_MIN + - (ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN) * ad_value / - ADC_RESOLUTION; - break; - - case MAIN_CHARGER_C: - case USB_CHARGER_C: - res = ADC_CH_CHG_I_MIN + - (ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN) * ad_value / - ADC_RESOLUTION; - break; - - case BK_BAT_V: - res = ADC_CH_BKBAT_MIN + - (ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN) * ad_value / - ADC_RESOLUTION; - break; - - default: - dev_err(gpadc->dev, - "unknown channel, not possible to convert\n"); - res = -EINVAL; - break; - - } - return res; -} -EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage); - -/** - * ab8500_gpadc_convert() - gpadc conversion - * @channel: analog channel to be converted to digital data - * - * This function converts the selected analog i/p to digital - * data. - */ -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 looplimit = 0; - u8 val, low_data, high_data; - - if (!gpadc) - return -ENODEV; - - mutex_lock(&gpadc->ab8500_gpadc_lock); - /* Enable VTVout LDO this is required for GPADC */ - regulator_enable(gpadc->regu); - - /* Check if ADC is not busy, lock and proceed */ - do { - ret = abx500_get_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_STAT_REG, &val); - if (ret < 0) - goto out; - if (!(val & GPADC_BUSY)) - break; - msleep(10); - } while (++looplimit < 10); - if (looplimit >= 10 && (val & GPADC_BUSY)) { - dev_err(gpadc->dev, "gpadc_conversion: GPADC busy"); - ret = -EINVAL; - goto out; - } - - /* Enable GPADC */ - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC); - if (ret < 0) { - dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n"); - goto out; - } - - /* Select the channel source and set average samples to 16 */ - ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16)); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: set avg samples failed\n"); - goto out; - } - - /* - * Enable ADC, buffering, select rising edge and enable ADC path - * charging current sense if it needed, ABB 3.0 needs some special - * treatment too. - */ - switch (channel) { - case MAIN_CHARGER_C: - case USB_CHARGER_C: - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_ICHAR, - EN_BUF | EN_ICHAR); - break; - case BTEMP_BALL: - if (gpadc->chip_id >= AB8500_CUT3P0) { - /* Turn on btemp pull-up on ABB 3.0 */ - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | BTEMP_PULL_UP, - EN_BUF | BTEMP_PULL_UP); - - /* - * Delay might be needed for ABB8500 cut 3.0, if not, remove - * when hardware will be availible - */ - msleep(1); - break; - } - /* Intentional fallthrough */ - default: - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF); - break; - } - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: select falling edge failed\n"); - goto out; - } - - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: start s/w conversion failed\n"); - goto out; - } - /* wait for completion of conversion */ - if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 2*HZ)) { - dev_err(gpadc->dev, - "timeout: didn't receive GPADC conversion interrupt\n"); - ret = -EINVAL; - goto out; - } - - /* Read the converted RAW data */ - ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_MANDATAL_REG, &low_data); - if (ret < 0) { - dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n"); - goto out; - } - - ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_MANDATAH_REG, &high_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read high data failed\n"); - goto out; - } - - /* Disable GPADC */ - ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_CTRL1_REG, DIS_GPADC); - if (ret < 0) { - dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n"); - goto out; - } - /* Disable VTVout LDO this is required for GPADC */ - regulator_disable(gpadc->regu); - mutex_unlock(&gpadc->ab8500_gpadc_lock); - - return (high_data << 8) | low_data; - -out: - /* - * It has shown to be needed to turn off the GPADC if an error occurs, - * otherwise we might have problem when waiting for the busy bit in the - * GPADC status register to go low. In V1.1 there wait_for_completion - * seems to timeout when waiting for an interrupt.. Not seen in V2.0 - */ - (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_CTRL1_REG, DIS_GPADC); - regulator_disable(gpadc->regu); - mutex_unlock(&gpadc->ab8500_gpadc_lock); - dev_err(gpadc->dev, - "gpadc_conversion: Failed to AD convert channel %d\n", channel); - return ret; -} -EXPORT_SYMBOL(ab8500_gpadc_read_raw); - -/** - * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion - * @irq: irq number - * @data: pointer to the data passed during request irq - * - * This is a interrupt service routine for s/w gpadc conversion completion. - * Notifies the gpadc completion is completed and the converted raw value - * can be read from the registers. - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc) -{ - struct ab8500_gpadc *gpadc = _gpadc; - - complete(&gpadc->ab8500_gpadc_complete); - - return IRQ_HANDLED; -} - -static int otp_cal_regs[] = { - AB8500_GPADC_CAL_1, - AB8500_GPADC_CAL_2, - AB8500_GPADC_CAL_3, - AB8500_GPADC_CAL_4, - AB8500_GPADC_CAL_5, - AB8500_GPADC_CAL_6, - AB8500_GPADC_CAL_7, -}; - -static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) -{ - int i; - int ret[ARRAY_SIZE(otp_cal_regs)]; - u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)]; - - int vmain_high, vmain_low; - int btemp_high, btemp_low; - int vbat_high, vbat_low; - - /* First we read all OTP registers and store the error code */ - for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) { - ret[i] = abx500_get_register_interruptible(gpadc->dev, - AB8500_OTP_EMUL, otp_cal_regs[i], &gpadc_cal[i]); - if (ret[i] < 0) - dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n", - __func__, otp_cal_regs[i]); - } - - /* - * The ADC calibration data is stored in OTP registers. - * The layout of the calibration data is outlined below and a more - * detailed description can be found in UM0836 - * - * vm_h/l = vmain_high/low - * bt_h/l = btemp_high/low - * vb_h/l = vbat_high/low - * - * Data bits: - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | | vm_h9 | vm_h8 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0 - * |.......|.......|.......|.......|.......|.......|.......|....... - * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | - * |.......|.......|.......|.......|.......|.......|.......|....... - * - * - * Ideal output ADC codes corresponding to injected input voltages - * during manufacturing is: - * - * vmain_high: Vin = 19500mV / ADC ideal code = 997 - * vmain_low: Vin = 315mV / ADC ideal code = 16 - * btemp_high: Vin = 1300mV / ADC ideal code = 985 - * btemp_low: Vin = 21mV / ADC ideal code = 16 - * vbat_high: Vin = 4700mV / ADC ideal code = 982 - * vbat_low: Vin = 2380mV / ADC ideal code = 33 - */ - - /* Calculate gain and offset for VMAIN if all reads succeeded */ - if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { - vmain_high = (((gpadc_cal[0] & 0x03) << 8) | - ((gpadc_cal[1] & 0x3F) << 2) | - ((gpadc_cal[2] & 0xC0) >> 6)); - - vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); - - gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * - (19500 - 315) / (vmain_high - vmain_low); - - gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 - - (CALIB_SCALE * (19500 - 315) / - (vmain_high - vmain_low)) * vmain_high; - } else { - gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; - } - - /* Calculate gain and offset for BTEMP if all reads succeeded */ - if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { - btemp_high = (((gpadc_cal[2] & 0x01) << 9) | - (gpadc_cal[3] << 1) | - ((gpadc_cal[4] & 0x80) >> 7)); - - btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); - - gpadc->cal_data[ADC_INPUT_BTEMP].gain = - CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); - - gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - - (CALIB_SCALE * (1300 - 21) / - (btemp_high - btemp_low)) * btemp_high; - } else { - gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0; - } - - /* Calculate gain and offset for VBAT if all reads succeeded */ - if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) { - vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]); - vbat_low = ((gpadc_cal[6] & 0xFC) >> 2); - - gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * - (4700 - 2380) / (vbat_high - vbat_low); - - gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - - (CALIB_SCALE * (4700 - 2380) / - (vbat_high - vbat_low)) * vbat_high; - } else { - gpadc->cal_data[ADC_INPUT_VBAT].gain = 0; - } - - dev_dbg(gpadc->dev, "VMAIN gain %llu offset %llu\n", - gpadc->cal_data[ADC_INPUT_VMAIN].gain, - gpadc->cal_data[ADC_INPUT_VMAIN].offset); - - dev_dbg(gpadc->dev, "BTEMP gain %llu offset %llu\n", - gpadc->cal_data[ADC_INPUT_BTEMP].gain, - gpadc->cal_data[ADC_INPUT_BTEMP].offset); - - dev_dbg(gpadc->dev, "VBAT gain %llu offset %llu\n", - gpadc->cal_data[ADC_INPUT_VBAT].gain, - gpadc->cal_data[ADC_INPUT_VBAT].offset); -} - -static int __devinit ab8500_gpadc_probe(struct platform_device *pdev) -{ - int ret = 0; - struct ab8500_gpadc *gpadc; - - gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL); - if (!gpadc) { - dev_err(&pdev->dev, "Error: No memory\n"); - return -ENOMEM; - } - - gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); - if (gpadc->irq < 0) { - dev_err(gpadc->dev, "failed to get platform irq-%d\n", - gpadc->irq); - ret = gpadc->irq; - goto fail; - } - - gpadc->dev = &pdev->dev; - mutex_init(&gpadc->ab8500_gpadc_lock); - - /* Initialize completion used to notify completion of conversion */ - init_completion(&gpadc->ab8500_gpadc_complete); - - /* Register interrupt - SwAdcComplete */ - ret = request_threaded_irq(gpadc->irq, NULL, - ab8500_bm_gpswadcconvend_handler, - IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc", gpadc); - if (ret < 0) { - dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", - gpadc->irq); - goto fail; - } - - /* Get Chip ID of the ABB ASIC */ - ret = abx500_get_chip_id(gpadc->dev); - if (ret < 0) { - dev_err(gpadc->dev, "failed to get chip ID\n"); - goto fail_irq; - } - gpadc->chip_id = (u8) ret; - - /* VTVout LDO used to power up ab8500-GPADC */ - gpadc->regu = regulator_get(&pdev->dev, "vddadc"); - if (IS_ERR(gpadc->regu)) { - ret = PTR_ERR(gpadc->regu); - dev_err(gpadc->dev, "failed to get vtvout LDO\n"); - goto fail_irq; - } - ab8500_gpadc_read_calibration_data(gpadc); - list_add_tail(&gpadc->node, &ab8500_gpadc_list); - dev_dbg(gpadc->dev, "probe success\n"); - return 0; -fail_irq: - free_irq(gpadc->irq, gpadc); -fail: - kfree(gpadc); - gpadc = NULL; - return ret; -} - -static int __devexit ab8500_gpadc_remove(struct platform_device *pdev) -{ - struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev); - - /* remove this gpadc entry from the list */ - list_del(&gpadc->node); - /* remove interrupt - completion of Sw ADC conversion */ - free_irq(gpadc->irq, gpadc); - /* disable VTVout LDO that is being used by GPADC */ - regulator_put(gpadc->regu); - kfree(gpadc); - gpadc = NULL; - return 0; -} - -static struct platform_driver ab8500_gpadc_driver = { - .probe = ab8500_gpadc_probe, - .remove = __devexit_p(ab8500_gpadc_remove), - .driver = { - .name = "ab8500-gpadc", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_gpadc_init(void) -{ - return platform_driver_register(&ab8500_gpadc_driver); -} - -static void __exit ab8500_gpadc_exit(void) -{ - platform_driver_unregister(&ab8500_gpadc_driver); -} - -subsys_initcall_sync(ab8500_gpadc_init); -module_exit(ab8500_gpadc_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson"); -MODULE_ALIAS("platform:ab8500_gpadc"); -MODULE_DESCRIPTION("AB8500 GPADC driver"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab8500-i2c.c b/ANDROID_3.4.5/drivers/mfd/ab8500-i2c.c deleted file mode 100644 index b83045f1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab8500-i2c.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson. - * License Terms: GNU General Public License v2 - * This file was based on drivers/mfd/ab8500-spi.c - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mfd/abx500/ab8500.h> -#include <linux/mfd/dbx500-prcmu.h> - -static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) -{ - int ret; - - ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); - if (ret < 0) - dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); - return ret; -} - -static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask, - u8 data) -{ - int ret; - - ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data, - &mask, 1); - if (ret < 0) - dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); - return ret; -} - -static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr) -{ - int ret; - u8 data; - - ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); - if (ret < 0) { - dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); - return ret; - } - return (int)data; -} - -static int __devinit ab8500_i2c_probe(struct platform_device *plf) -{ - const struct platform_device_id *platid = platform_get_device_id(plf); - struct ab8500 *ab8500; - struct resource *resource; - int ret; - - ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); - if (!ab8500) - return -ENOMEM; - - ab8500->dev = &plf->dev; - - resource = platform_get_resource(plf, IORESOURCE_IRQ, 0); - if (!resource) { - kfree(ab8500); - return -ENODEV; - } - - ab8500->irq = resource->start; - - ab8500->read = ab8500_i2c_read; - ab8500->write = ab8500_i2c_write; - ab8500->write_masked = ab8500_i2c_write_masked; - - platform_set_drvdata(plf, ab8500); - - ret = ab8500_init(ab8500, platid->driver_data); - if (ret) - kfree(ab8500); - - - return ret; -} - -static int __devexit ab8500_i2c_remove(struct platform_device *plf) -{ - struct ab8500 *ab8500 = platform_get_drvdata(plf); - - ab8500_exit(ab8500); - kfree(ab8500); - - return 0; -} - -static const struct platform_device_id ab8500_id[] = { - { "ab8500-i2c", AB8500_VERSION_AB8500 }, - { "ab8505-i2c", AB8500_VERSION_AB8505 }, - { "ab9540-i2c", AB8500_VERSION_AB9540 }, - { "ab8540-i2c", AB8500_VERSION_AB8540 }, - { } -}; - -static struct platform_driver ab8500_i2c_driver = { - .driver = { - .name = "ab8500-i2c", - .owner = THIS_MODULE, - }, - .probe = ab8500_i2c_probe, - .remove = __devexit_p(ab8500_i2c_remove), - .id_table = ab8500_id, -}; - -static int __init ab8500_i2c_init(void) -{ - return platform_driver_register(&ab8500_i2c_driver); -} - -static void __exit ab8500_i2c_exit(void) -{ - platform_driver_unregister(&ab8500_i2c_driver); -} -arch_initcall(ab8500_i2c_init); -module_exit(ab8500_i2c_exit); - -MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com"); -MODULE_DESCRIPTION("AB8500 Core access via PRCMU I2C"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/ab8500-sysctrl.c b/ANDROID_3.4.5/drivers/mfd/ab8500-sysctrl.c deleted file mode 100644 index c28d4eb1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ab8500-sysctrl.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson. - * License terms: GNU General Public License (GPL) version 2 - */ - -#include <linux/err.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mfd/abx500.h> -#include <linux/mfd/abx500/ab8500.h> -#include <linux/mfd/abx500/ab8500-sysctrl.h> - -static struct device *sysctrl_dev; - -static inline bool valid_bank(u8 bank) -{ - return ((bank == AB8500_SYS_CTRL1_BLOCK) || - (bank == AB8500_SYS_CTRL2_BLOCK)); -} - -int ab8500_sysctrl_read(u16 reg, u8 *value) -{ - u8 bank; - - if (sysctrl_dev == NULL) - return -EAGAIN; - - bank = (reg >> 8); - if (!valid_bank(bank)) - return -EINVAL; - - return abx500_get_register_interruptible(sysctrl_dev, bank, - (u8)(reg & 0xFF), value); -} - -int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) -{ - u8 bank; - - if (sysctrl_dev == NULL) - return -EAGAIN; - - bank = (reg >> 8); - if (!valid_bank(bank)) - return -EINVAL; - - return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank, - (u8)(reg & 0xFF), mask, value); -} - -static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev) -{ - sysctrl_dev = &pdev->dev; - return 0; -} - -static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev) -{ - sysctrl_dev = NULL; - return 0; -} - -static struct platform_driver ab8500_sysctrl_driver = { - .driver = { - .name = "ab8500-sysctrl", - .owner = THIS_MODULE, - }, - .probe = ab8500_sysctrl_probe, - .remove = __devexit_p(ab8500_sysctrl_remove), -}; - -static int __init ab8500_sysctrl_init(void) -{ - return platform_driver_register(&ab8500_sysctrl_driver); -} -subsys_initcall(ab8500_sysctrl_init); - -MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com"); -MODULE_DESCRIPTION("AB8500 system control driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/abx500-core.c b/ANDROID_3.4.5/drivers/mfd/abx500-core.c deleted file mode 100644 index 7ce65f49..00000000 --- a/ANDROID_3.4.5/drivers/mfd/abx500-core.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2007-2010 ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - * Register access functions for the ABX500 Mixed Signal IC family. - * Author: Mattias Wallin <mattias.wallin@stericsson.com> - */ - -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/module.h> -#include <linux/mfd/abx500.h> - -static LIST_HEAD(abx500_list); - -struct abx500_device_entry { - struct list_head list; - struct abx500_ops ops; - struct device *dev; -}; - -static void lookup_ops(struct device *dev, struct abx500_ops **ops) -{ - struct abx500_device_entry *dev_entry; - - *ops = NULL; - list_for_each_entry(dev_entry, &abx500_list, list) { - if (dev_entry->dev == dev) { - *ops = &dev_entry->ops; - return; - } - } -} - -int abx500_register_ops(struct device *dev, struct abx500_ops *ops) -{ - struct abx500_device_entry *dev_entry; - - dev_entry = kzalloc(sizeof(struct abx500_device_entry), GFP_KERNEL); - if (!dev_entry) { - dev_err(dev, "register_ops kzalloc failed"); - return -ENOMEM; - } - dev_entry->dev = dev; - memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops)); - - list_add_tail(&dev_entry->list, &abx500_list); - return 0; -} -EXPORT_SYMBOL(abx500_register_ops); - -void abx500_remove_ops(struct device *dev) -{ - struct abx500_device_entry *dev_entry, *tmp; - - list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list) - { - if (dev_entry->dev == dev) { - list_del(&dev_entry->list); - kfree(dev_entry); - } - } -} -EXPORT_SYMBOL(abx500_remove_ops); - -int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, - u8 value) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->set_register != NULL)) - return ops->set_register(dev, bank, reg, value); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_set_register_interruptible); - -int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, - u8 *value) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_register != NULL)) - return ops->get_register(dev, bank, reg, value); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_get_register_interruptible); - -int abx500_get_register_page_interruptible(struct device *dev, u8 bank, - u8 first_reg, u8 *regvals, u8 numregs) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_register_page != NULL)) - return ops->get_register_page(dev, bank, - first_reg, regvals, numregs); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_get_register_page_interruptible); - -int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank, - u8 reg, u8 bitmask, u8 bitvalues) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->mask_and_set_register != NULL)) - return ops->mask_and_set_register(dev, bank, - reg, bitmask, bitvalues); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_mask_and_set_register_interruptible); - -int abx500_get_chip_id(struct device *dev) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_chip_id != NULL)) - return ops->get_chip_id(dev); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_get_chip_id); - -int abx500_event_registers_startup_state_get(struct device *dev, u8 *event) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL)) - return ops->event_registers_startup_state_get(dev, event); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_event_registers_startup_state_get); - -int abx500_startup_irq_enabled(struct device *dev, unsigned int irq) -{ - struct abx500_ops *ops; - - lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->startup_irq_enabled != NULL)) - return ops->startup_irq_enabled(dev, irq); - else - return -ENOTSUPP; -} -EXPORT_SYMBOL(abx500_startup_irq_enabled); - -MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); -MODULE_DESCRIPTION("ABX500 core driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/adp5520.c b/ANDROID_3.4.5/drivers/mfd/adp5520.c deleted file mode 100644 index 8d816cce..00000000 --- a/ANDROID_3.4.5/drivers/mfd/adp5520.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Base driver for Analog Devices ADP5520/ADP5501 MFD PMICs - * LCD Backlight: drivers/video/backlight/adp5520_bl - * LEDs : drivers/led/leds-adp5520 - * GPIO : drivers/gpio/adp5520-gpio (ADP5520 only) - * Keys : drivers/input/keyboard/adp5520-keys (ADP5520 only) - * - * Copyright 2009 Analog Devices Inc. - * - * Derived from da903x: - * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport <mike@compulab.co.il> - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao <eric.miao@marvell.com> - * - * Licensed under the GPL-2 or later. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/i2c.h> - -#include <linux/mfd/adp5520.h> - -struct adp5520_chip { - struct i2c_client *client; - struct device *dev; - struct mutex lock; - struct blocking_notifier_head notifier_list; - int irq; - unsigned long id; -}; - -static int __adp5520_read(struct i2c_client *client, - int reg, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "failed reading at 0x%02x\n", reg); - return ret; - } - - *val = (uint8_t)ret; - return 0; -} - -static int __adp5520_write(struct i2c_client *client, - int reg, uint8_t val) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, val); - if (ret < 0) { - dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", - val, reg); - return ret; - } - return 0; -} - -static int __adp5520_ack_bits(struct i2c_client *client, int reg, - uint8_t bit_mask) -{ - struct adp5520_chip *chip = i2c_get_clientdata(client); - uint8_t reg_val; - int ret; - - mutex_lock(&chip->lock); - - ret = __adp5520_read(client, reg, ®_val); - - if (!ret) { - reg_val |= bit_mask; - ret = __adp5520_write(client, reg, reg_val); - } - - mutex_unlock(&chip->lock); - return ret; -} - -int adp5520_write(struct device *dev, int reg, uint8_t val) -{ - return __adp5520_write(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(adp5520_write); - -int adp5520_read(struct device *dev, int reg, uint8_t *val) -{ - return __adp5520_read(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(adp5520_read); - -int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct adp5520_chip *chip = dev_get_drvdata(dev); - uint8_t reg_val; - int ret; - - mutex_lock(&chip->lock); - - ret = __adp5520_read(chip->client, reg, ®_val); - - if (!ret && ((reg_val & bit_mask) != bit_mask)) { - reg_val |= bit_mask; - ret = __adp5520_write(chip->client, reg, reg_val); - } - - mutex_unlock(&chip->lock); - return ret; -} -EXPORT_SYMBOL_GPL(adp5520_set_bits); - -int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct adp5520_chip *chip = dev_get_drvdata(dev); - uint8_t reg_val; - int ret; - - mutex_lock(&chip->lock); - - ret = __adp5520_read(chip->client, reg, ®_val); - - if (!ret && (reg_val & bit_mask)) { - reg_val &= ~bit_mask; - ret = __adp5520_write(chip->client, reg, reg_val); - } - - mutex_unlock(&chip->lock); - return ret; -} -EXPORT_SYMBOL_GPL(adp5520_clr_bits); - -int adp5520_register_notifier(struct device *dev, struct notifier_block *nb, - unsigned int events) -{ - struct adp5520_chip *chip = dev_get_drvdata(dev); - - if (chip->irq) { - adp5520_set_bits(chip->dev, ADP5520_INTERRUPT_ENABLE, - events & (ADP5520_KP_IEN | ADP5520_KR_IEN | - ADP5520_OVP_IEN | ADP5520_CMPR_IEN)); - - return blocking_notifier_chain_register(&chip->notifier_list, - nb); - } - - return -ENODEV; -} -EXPORT_SYMBOL_GPL(adp5520_register_notifier); - -int adp5520_unregister_notifier(struct device *dev, struct notifier_block *nb, - unsigned int events) -{ - struct adp5520_chip *chip = dev_get_drvdata(dev); - - adp5520_clr_bits(chip->dev, ADP5520_INTERRUPT_ENABLE, - events & (ADP5520_KP_IEN | ADP5520_KR_IEN | - ADP5520_OVP_IEN | ADP5520_CMPR_IEN)); - - return blocking_notifier_chain_unregister(&chip->notifier_list, nb); -} -EXPORT_SYMBOL_GPL(adp5520_unregister_notifier); - -static irqreturn_t adp5520_irq_thread(int irq, void *data) -{ - struct adp5520_chip *chip = data; - unsigned int events; - uint8_t reg_val; - int ret; - - ret = __adp5520_read(chip->client, ADP5520_MODE_STATUS, ®_val); - if (ret) - goto out; - - events = reg_val & (ADP5520_OVP_INT | ADP5520_CMPR_INT | - ADP5520_GPI_INT | ADP5520_KR_INT | ADP5520_KP_INT); - - blocking_notifier_call_chain(&chip->notifier_list, events, NULL); - /* ACK, Sticky bits are W1C */ - __adp5520_ack_bits(chip->client, ADP5520_MODE_STATUS, events); - -out: - return IRQ_HANDLED; -} - -static int __remove_subdev(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - -static int adp5520_remove_subdevs(struct adp5520_chip *chip) -{ - return device_for_each_child(chip->dev, NULL, __remove_subdev); -} - -static int __devinit adp5520_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct adp5520_platform_data *pdata = client->dev.platform_data; - struct platform_device *pdev; - struct adp5520_chip *chip; - int ret; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "SMBUS Word Data not Supported\n"); - return -EIO; - } - - if (pdata == NULL) { - dev_err(&client->dev, "missing platform data\n"); - return -ENODEV; - } - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - i2c_set_clientdata(client, chip); - chip->client = client; - - chip->dev = &client->dev; - chip->irq = client->irq; - chip->id = id->driver_data; - mutex_init(&chip->lock); - - if (chip->irq) { - BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list); - - ret = request_threaded_irq(chip->irq, NULL, adp5520_irq_thread, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "adp5520", chip); - if (ret) { - dev_err(&client->dev, "failed to request irq %d\n", - chip->irq); - goto out_free_chip; - } - } - - ret = adp5520_write(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); - if (ret) { - dev_err(&client->dev, "failed to write\n"); - goto out_free_irq; - } - - if (pdata->keys) { - pdev = platform_device_register_data(chip->dev, "adp5520-keys", - chip->id, pdata->keys, sizeof(*pdata->keys)); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto out_remove_subdevs; - } - } - - if (pdata->gpio) { - pdev = platform_device_register_data(chip->dev, "adp5520-gpio", - chip->id, pdata->gpio, sizeof(*pdata->gpio)); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto out_remove_subdevs; - } - } - - if (pdata->leds) { - pdev = platform_device_register_data(chip->dev, "adp5520-led", - chip->id, pdata->leds, sizeof(*pdata->leds)); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto out_remove_subdevs; - } - } - - if (pdata->backlight) { - pdev = platform_device_register_data(chip->dev, - "adp5520-backlight", - chip->id, - pdata->backlight, - sizeof(*pdata->backlight)); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto out_remove_subdevs; - } - } - - return 0; - -out_remove_subdevs: - adp5520_remove_subdevs(chip); - -out_free_irq: - if (chip->irq) - free_irq(chip->irq, chip); - -out_free_chip: - kfree(chip); - - return ret; -} - -static int __devexit adp5520_remove(struct i2c_client *client) -{ - struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - - if (chip->irq) - free_irq(chip->irq, chip); - - adp5520_remove_subdevs(chip); - adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); - kfree(chip); - return 0; -} - -#ifdef CONFIG_PM -static int adp5520_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - - adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); - return 0; -} - -static int adp5520_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - - adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume); - -static const struct i2c_device_id adp5520_id[] = { - { "pmic-adp5520", ID_ADP5520 }, - { "pmic-adp5501", ID_ADP5501 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, adp5520_id); - -static struct i2c_driver adp5520_driver = { - .driver = { - .name = "adp5520", - .owner = THIS_MODULE, - .pm = &adp5520_pm, - }, - .probe = adp5520_probe, - .remove = __devexit_p(adp5520_remove), - .id_table = adp5520_id, -}; - -static int __init adp5520_init(void) -{ - return i2c_add_driver(&adp5520_driver); -} -module_init(adp5520_init); - -static void __exit adp5520_exit(void) -{ - i2c_del_driver(&adp5520_driver); -} -module_exit(adp5520_exit); - -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); -MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/anatop-mfd.c b/ANDROID_3.4.5/drivers/mfd/anatop-mfd.c deleted file mode 100644 index 2af42480..00000000 --- a/ANDROID_3.4.5/drivers/mfd/anatop-mfd.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Anatop MFD driver - * - * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org> - * Copyright (C) 2012 Linaro - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, Fifth Floor, Boston, MA 02110-1301 USA. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <linux/io.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_platform.h> -#include <linux/of_address.h> -#include <linux/mfd/anatop.h> - -u32 anatop_get_bits(struct anatop *adata, u32 addr, int bit_shift, - int bit_width) -{ - u32 val, mask; - - if (bit_width == 32) - mask = ~0; - else - mask = (1 << bit_width) - 1; - - val = readl(adata->ioreg + addr); - val = (val >> bit_shift) & mask; - - return val; -} -EXPORT_SYMBOL_GPL(anatop_get_bits); - -void anatop_set_bits(struct anatop *adata, u32 addr, int bit_shift, - int bit_width, u32 data) -{ - u32 val, mask; - - if (bit_width == 32) - mask = ~0; - else - mask = (1 << bit_width) - 1; - - spin_lock(&adata->reglock); - val = readl(adata->ioreg + addr) & ~(mask << bit_shift); - writel((data << bit_shift) | val, adata->ioreg + addr); - spin_unlock(&adata->reglock); -} -EXPORT_SYMBOL_GPL(anatop_set_bits); - -static const struct of_device_id of_anatop_match[] = { - { .compatible = "fsl,imx6q-anatop", }, - { }, -}; - -static int __devinit of_anatop_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - void *ioreg; - struct anatop *drvdata; - - ioreg = of_iomap(np, 0); - if (!ioreg) - return -EADDRNOTAVAIL; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - drvdata->ioreg = ioreg; - spin_lock_init(&drvdata->reglock); - platform_set_drvdata(pdev, drvdata); - of_platform_populate(np, of_anatop_match, NULL, dev); - - return 0; -} - -static int __devexit of_anatop_remove(struct platform_device *pdev) -{ - struct anatop *drvdata; - drvdata = platform_get_drvdata(pdev); - iounmap(drvdata->ioreg); - - return 0; -} - -static struct platform_driver anatop_of_driver = { - .driver = { - .name = "anatop-mfd", - .owner = THIS_MODULE, - .of_match_table = of_anatop_match, - }, - .probe = of_anatop_probe, - .remove = of_anatop_remove, -}; - -static int __init anatop_init(void) -{ - return platform_driver_register(&anatop_of_driver); -} -postcore_initcall(anatop_init); - -static void __exit anatop_exit(void) -{ - platform_driver_unregister(&anatop_of_driver); -} -module_exit(anatop_exit); - -MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>"); -MODULE_DESCRIPTION("ANATOP MFD driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/asic3.c b/ANDROID_3.4.5/drivers/mfd/asic3.c deleted file mode 100644 index 1582c3d9..00000000 --- a/ANDROID_3.4.5/drivers/mfd/asic3.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * driver/mfd/asic3.c - * - * Compaq ASIC3 support. - * - * 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. - * - * Copyright 2001 Compaq Computer Corporation. - * Copyright 2004-2005 Phil Blundell - * Copyright 2007-2008 OpenedHand Ltd. - * - * Authors: Phil Blundell <pb@handhelds.org>, - * Samuel Ortiz <sameo@openedhand.com> - * - */ - -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/export.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/platform_device.h> - -#include <linux/mfd/asic3.h> -#include <linux/mfd/core.h> -#include <linux/mfd/ds1wm.h> -#include <linux/mfd/tmio.h> - -enum { - ASIC3_CLOCK_SPI, - ASIC3_CLOCK_OWM, - ASIC3_CLOCK_PWM0, - ASIC3_CLOCK_PWM1, - ASIC3_CLOCK_LED0, - ASIC3_CLOCK_LED1, - ASIC3_CLOCK_LED2, - ASIC3_CLOCK_SD_HOST, - ASIC3_CLOCK_SD_BUS, - ASIC3_CLOCK_SMBUS, - ASIC3_CLOCK_EX0, - ASIC3_CLOCK_EX1, -}; - -struct asic3_clk { - int enabled; - unsigned int cdex; - unsigned long rate; -}; - -#define INIT_CDEX(_name, _rate) \ - [ASIC3_CLOCK_##_name] = { \ - .cdex = CLOCK_CDEX_##_name, \ - .rate = _rate, \ - } - -static struct asic3_clk asic3_clk_init[] __initdata = { - INIT_CDEX(SPI, 0), - INIT_CDEX(OWM, 5000000), - INIT_CDEX(PWM0, 0), - INIT_CDEX(PWM1, 0), - INIT_CDEX(LED0, 0), - INIT_CDEX(LED1, 0), - INIT_CDEX(LED2, 0), - INIT_CDEX(SD_HOST, 24576000), - INIT_CDEX(SD_BUS, 12288000), - INIT_CDEX(SMBUS, 0), - INIT_CDEX(EX0, 32768), - INIT_CDEX(EX1, 24576000), -}; - -struct asic3 { - void __iomem *mapping; - unsigned int bus_shift; - unsigned int irq_nr; - unsigned int irq_base; - spinlock_t lock; - u16 irq_bothedge[4]; - struct gpio_chip gpio; - struct device *dev; - void __iomem *tmio_cnf; - - struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; -}; - -static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset); - -void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 value) -{ - iowrite16(value, asic->mapping + - (reg >> asic->bus_shift)); -} -EXPORT_SYMBOL_GPL(asic3_write_register); - -u32 asic3_read_register(struct asic3 *asic, unsigned int reg) -{ - return ioread16(asic->mapping + - (reg >> asic->bus_shift)); -} -EXPORT_SYMBOL_GPL(asic3_read_register); - -static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, reg); - if (set) - val |= bits; - else - val &= ~bits; - asic3_write_register(asic, reg, val); - spin_unlock_irqrestore(&asic->lock, flags); -} - -/* IRQs */ -#define MAX_ASIC_ISR_LOOPS 20 -#define ASIC3_GPIO_BASE_INCR \ - (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE) - -static void asic3_irq_flip_edge(struct asic3 *asic, - u32 base, int bit) -{ - u16 edge; - unsigned long flags; - - spin_lock_irqsave(&asic->lock, flags); - edge = asic3_read_register(asic, - base + ASIC3_GPIO_EDGE_TRIGGER); - edge ^= bit; - asic3_write_register(asic, - base + ASIC3_GPIO_EDGE_TRIGGER, edge); - spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) -{ - struct asic3 *asic = irq_desc_get_handler_data(desc); - struct irq_data *data = irq_desc_get_irq_data(desc); - int iter, i; - unsigned long flags; - - data->chip->irq_ack(data); - - for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { - u32 status; - int bank; - - spin_lock_irqsave(&asic->lock, flags); - status = asic3_read_register(asic, - ASIC3_OFFSET(INTR, P_INT_STAT)); - spin_unlock_irqrestore(&asic->lock, flags); - - /* Check all ten register bits */ - if ((status & 0x3ff) == 0) - break; - - /* Handle GPIO IRQs */ - for (bank = 0; bank < ASIC3_NUM_GPIO_BANKS; bank++) { - if (status & (1 << bank)) { - unsigned long base, istat; - - base = ASIC3_GPIO_A_BASE - + bank * ASIC3_GPIO_BASE_INCR; - - spin_lock_irqsave(&asic->lock, flags); - istat = asic3_read_register(asic, - base + - ASIC3_GPIO_INT_STATUS); - /* Clearing IntStatus */ - asic3_write_register(asic, - base + - ASIC3_GPIO_INT_STATUS, 0); - spin_unlock_irqrestore(&asic->lock, flags); - - for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) { - int bit = (1 << i); - unsigned int irqnr; - - if (!(istat & bit)) - continue; - - irqnr = asic->irq_base + - (ASIC3_GPIOS_PER_BANK * bank) - + i; - generic_handle_irq(irqnr); - if (asic->irq_bothedge[bank] & bit) - asic3_irq_flip_edge(asic, base, - bit); - } - } - } - - /* Handle remaining IRQs in the status register */ - for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { - /* They start at bit 4 and go up */ - if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) - generic_handle_irq(asic->irq_base + i); - } - } - - if (iter >= MAX_ASIC_ISR_LOOPS) - dev_err(asic->dev, "interrupt processing overrun\n"); -} - -static inline int asic3_irq_to_bank(struct asic3 *asic, int irq) -{ - int n; - - n = (irq - asic->irq_base) >> 4; - - return (n * (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE)); -} - -static inline int asic3_irq_to_index(struct asic3 *asic, int irq) -{ - return (irq - asic->irq_base) & 0xf; -} - -static void asic3_mask_gpio_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 val, bank, index; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - - spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); - val |= 1 << index; - asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); - spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_mask_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - int regval; - unsigned long flags; - - spin_lock_irqsave(&asic->lock, flags); - regval = asic3_read_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK); - - regval &= ~(ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); - - asic3_write_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK, - regval); - spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_unmask_gpio_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 val, bank, index; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - - spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); - val &= ~(1 << index); - asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); - spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_unmask_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - int regval; - unsigned long flags; - - spin_lock_irqsave(&asic->lock, flags); - regval = asic3_read_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK); - - regval |= (ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); - - asic3_write_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK, - regval); - spin_unlock_irqrestore(&asic->lock, flags); -} - -static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 bank, index; - u16 trigger, level, edge, bit; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - bit = 1<<index; - - spin_lock_irqsave(&asic->lock, flags); - level = asic3_read_register(asic, - bank + ASIC3_GPIO_LEVEL_TRIGGER); - edge = asic3_read_register(asic, - bank + ASIC3_GPIO_EDGE_TRIGGER); - trigger = asic3_read_register(asic, - bank + ASIC3_GPIO_TRIGGER_TYPE); - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] &= ~bit; - - if (type == IRQ_TYPE_EDGE_RISING) { - trigger |= bit; - edge |= bit; - } else if (type == IRQ_TYPE_EDGE_FALLING) { - trigger |= bit; - edge &= ~bit; - } else if (type == IRQ_TYPE_EDGE_BOTH) { - trigger |= bit; - if (asic3_gpio_get(&asic->gpio, data->irq - asic->irq_base)) - edge &= ~bit; - else - edge |= bit; - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] |= bit; - } else if (type == IRQ_TYPE_LEVEL_LOW) { - trigger &= ~bit; - level &= ~bit; - } else if (type == IRQ_TYPE_LEVEL_HIGH) { - trigger &= ~bit; - level |= bit; - } else { - /* - * if type == IRQ_TYPE_NONE, we should mask interrupts, but - * be careful to not unmask them if mask was also called. - * Probably need internal state for mask. - */ - dev_notice(asic->dev, "irq type not changed\n"); - } - asic3_write_register(asic, bank + ASIC3_GPIO_LEVEL_TRIGGER, - level); - asic3_write_register(asic, bank + ASIC3_GPIO_EDGE_TRIGGER, - edge); - asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE, - trigger); - spin_unlock_irqrestore(&asic->lock, flags); - return 0; -} - -static struct irq_chip asic3_gpio_irq_chip = { - .name = "ASIC3-GPIO", - .irq_ack = asic3_mask_gpio_irq, - .irq_mask = asic3_mask_gpio_irq, - .irq_unmask = asic3_unmask_gpio_irq, - .irq_set_type = asic3_gpio_irq_type, -}; - -static struct irq_chip asic3_irq_chip = { - .name = "ASIC3", - .irq_ack = asic3_mask_irq, - .irq_mask = asic3_mask_irq, - .irq_unmask = asic3_unmask_irq, -}; - -static int __init asic3_irq_probe(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - unsigned long clksel = 0; - unsigned int irq, irq_base; - int ret; - - ret = platform_get_irq(pdev, 0); - if (ret < 0) - return ret; - asic->irq_nr = ret; - - /* turn on clock to IRQ controller */ - clksel |= CLOCK_SEL_CX; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), - clksel); - - irq_base = asic->irq_base; - - for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { - if (irq < asic->irq_base + ASIC3_NUM_GPIOS) - irq_set_chip(irq, &asic3_gpio_irq_chip); - else - irq_set_chip(irq, &asic3_irq_chip); - - irq_set_chip_data(irq, asic); - irq_set_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), - ASIC3_INTMASK_GINTMASK); - - irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); - irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(asic->irq_nr, asic); - - return 0; -} - -static void asic3_irq_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - unsigned int irq, irq_base; - - irq_base = asic->irq_base; - - for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { - set_irq_flags(irq, 0); - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); - } - irq_set_chained_handler(asic->irq_nr, NULL); -} - -/* GPIOs */ -static int asic3_gpio_direction(struct gpio_chip *chip, - unsigned offset, int out) -{ - u32 mask = ASIC3_GPIO_TO_MASK(offset), out_reg; - unsigned int gpio_base; - unsigned long flags; - struct asic3 *asic; - - asic = container_of(chip, struct asic3, gpio); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return -EINVAL; - } - - spin_lock_irqsave(&asic->lock, flags); - - out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION); - - /* Input is 0, Output is 1 */ - if (out) - out_reg |= mask; - else - out_reg &= ~mask; - - asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg); - - spin_unlock_irqrestore(&asic->lock, flags); - - return 0; - -} - -static int asic3_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - return asic3_gpio_direction(chip, offset, 0); -} - -static int asic3_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - return asic3_gpio_direction(chip, offset, 1); -} - -static int asic3_gpio_get(struct gpio_chip *chip, - unsigned offset) -{ - unsigned int gpio_base; - u32 mask = ASIC3_GPIO_TO_MASK(offset); - struct asic3 *asic; - - asic = container_of(chip, struct asic3, gpio); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return -EINVAL; - } - - return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask; -} - -static void asic3_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - u32 mask, out_reg; - unsigned int gpio_base; - unsigned long flags; - struct asic3 *asic; - - asic = container_of(chip, struct asic3, gpio); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return; - } - - mask = ASIC3_GPIO_TO_MASK(offset); - - spin_lock_irqsave(&asic->lock, flags); - - out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT); - - if (value) - out_reg |= mask; - else - out_reg &= ~mask; - - asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg); - - spin_unlock_irqrestore(&asic->lock, flags); - - return; -} - -static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct asic3 *asic = container_of(chip, struct asic3, gpio); - - return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; -} - -static __init int asic3_gpio_probe(struct platform_device *pdev, - u16 *gpio_config, int num) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - u16 alt_reg[ASIC3_NUM_GPIO_BANKS]; - u16 out_reg[ASIC3_NUM_GPIO_BANKS]; - u16 dir_reg[ASIC3_NUM_GPIO_BANKS]; - int i; - - memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - - /* Enable all GPIOs */ - asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, MASK), 0xffff); - - for (i = 0; i < num; i++) { - u8 alt, pin, dir, init, bank_num, bit_num; - u16 config = gpio_config[i]; - - pin = ASIC3_CONFIG_GPIO_PIN(config); - alt = ASIC3_CONFIG_GPIO_ALT(config); - dir = ASIC3_CONFIG_GPIO_DIR(config); - init = ASIC3_CONFIG_GPIO_INIT(config); - - bank_num = ASIC3_GPIO_TO_BANK(pin); - bit_num = ASIC3_GPIO_TO_BIT(pin); - - alt_reg[bank_num] |= (alt << bit_num); - out_reg[bank_num] |= (init << bit_num); - dir_reg[bank_num] |= (dir << bit_num); - } - - for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) { - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + - ASIC3_GPIO_DIRECTION, - dir_reg[i]); - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_OUT, - out_reg[i]); - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + - ASIC3_GPIO_ALT_FUNCTION, - alt_reg[i]); - } - - return gpiochip_add(&asic->gpio); -} - -static int asic3_gpio_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - - return gpiochip_remove(&asic->gpio); -} - -static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) -{ - unsigned long flags; - u32 cdex; - - spin_lock_irqsave(&asic->lock, flags); - if (clk->enabled++ == 0) { - cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX)); - cdex |= clk->cdex; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); - } - spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk) -{ - unsigned long flags; - u32 cdex; - - WARN_ON(clk->enabled == 0); - - spin_lock_irqsave(&asic->lock, flags); - if (--clk->enabled == 0) { - cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX)); - cdex &= ~clk->cdex; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); - } - spin_unlock_irqrestore(&asic->lock, flags); -} - -/* MFD cells (SPI, PWM, LED, DS1WM, MMC) */ -static struct ds1wm_driver_data ds1wm_pdata = { - .active_high = 1, - .reset_recover_delay = 1, -}; - -static struct resource ds1wm_resources[] = { - { - .start = ASIC3_OWM_BASE, - .end = ASIC3_OWM_BASE + 0x13, - .flags = IORESOURCE_MEM, - }, - { - .start = ASIC3_IRQ_OWM, - .end = ASIC3_IRQ_OWM, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - }, -}; - -static int ds1wm_enable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Turn on external clocks and the OWM clock */ - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]); - msleep(1); - - /* Reset and enable DS1WM */ - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), - ASIC3_EXTCF_OWM_RESET, 1); - msleep(1); - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), - ASIC3_EXTCF_OWM_RESET, 0); - msleep(1); - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_EN, 1); - msleep(1); - - return 0; -} - -static int ds1wm_disable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_EN, 0); - - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_OWM]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - - return 0; -} - -static struct mfd_cell asic3_cell_ds1wm = { - .name = "ds1wm", - .enable = ds1wm_enable, - .disable = ds1wm_disable, - .platform_data = &ds1wm_pdata, - .pdata_size = sizeof(ds1wm_pdata), - .num_resources = ARRAY_SIZE(ds1wm_resources), - .resources = ds1wm_resources, -}; - -static void asic3_mmc_pwr(struct platform_device *pdev, int state) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - tmio_core_mmc_pwr(asic->tmio_cnf, 1 - asic->bus_shift, state); -} - -static void asic3_mmc_clk_div(struct platform_device *pdev, int state) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - tmio_core_mmc_clk_div(asic->tmio_cnf, 1 - asic->bus_shift, state); -} - -static struct tmio_mmc_data asic3_mmc_data = { - .hclk = 24576000, - .set_pwr = asic3_mmc_pwr, - .set_clk_div = asic3_mmc_clk_div, -}; - -static struct resource asic3_mmc_resources[] = { - { - .start = ASIC3_SD_CTRL_BASE, - .end = ASIC3_SD_CTRL_BASE + 0x3ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, -}; - -static int asic3_mmc_enable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Not sure if it must be done bit by bit, but leaving as-is */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_LEVCD, 1); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_LEVWP, 1); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SUSPEND, 0); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_PCLR, 0); - - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - /* CLK32 used for card detection and for interruption detection - * when HCLK is stopped. - */ - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - msleep(1); - - /* HCLK 24.576 MHz, BCLK 12.288 MHz: */ - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), - CLOCK_SEL_CX | CLOCK_SEL_SD_HCLK_SEL); - - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]); - msleep(1); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_SD_MEM_ENABLE, 1); - - /* Enable SD card slot 3.3V power supply */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SDPWR, 1); - - /* ASIC3_SD_CTRL_BASE assumes 32-bit addressing, TMIO is 16-bit */ - tmio_core_mmc_enable(asic->tmio_cnf, 1 - asic->bus_shift, - ASIC3_SD_CTRL_BASE >> 1); - - return 0; -} - -static int asic3_mmc_disable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Put in suspend mode */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SUSPEND, 1); - - /* Disable clocks */ - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - return 0; -} - -static struct mfd_cell asic3_cell_mmc = { - .name = "tmio-mmc", - .enable = asic3_mmc_enable, - .disable = asic3_mmc_disable, - .suspend = asic3_mmc_disable, - .resume = asic3_mmc_enable, - .platform_data = &asic3_mmc_data, - .pdata_size = sizeof(asic3_mmc_data), - .num_resources = ARRAY_SIZE(asic3_mmc_resources), - .resources = asic3_mmc_resources, -}; - -static const int clock_ledn[ASIC3_NUM_LEDS] = { - [0] = ASIC3_CLOCK_LED0, - [1] = ASIC3_CLOCK_LED1, - [2] = ASIC3_CLOCK_LED2, -}; - -static int asic3_leds_enable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_clk_enable(asic, &asic->clocks[clock_ledn[cell->id]]); - - return 0; -} - -static int asic3_leds_disable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); - - 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] = { - [0] = { - .name = "leds-asic3", - .id = 0, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, - [1] = { - .name = "leds-asic3", - .id = 1, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, - [2] = { - .name = "leds-asic3", - .id = 2, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, -}; - -static int __init asic3_mfd_probe(struct platform_device *pdev, - struct asic3_platform_data *pdata, - struct resource *mem) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - struct resource *mem_sdio; - int irq, ret; - - mem_sdio = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!mem_sdio) - dev_dbg(asic->dev, "no SDIO MEM resource\n"); - - irq = platform_get_irq(pdev, 1); - if (irq < 0) - dev_dbg(asic->dev, "no SDIO IRQ resource\n"); - - /* DS1WM */ - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_SMB, 0); - - ds1wm_resources[0].start >>= asic->bus_shift; - ds1wm_resources[0].end >>= asic->bus_shift; - - /* MMC */ - asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + - mem_sdio->start, - ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); - if (!asic->tmio_cnf) { - ret = -ENOMEM; - dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); - goto out; - } - asic3_mmc_resources[0].start >>= asic->bus_shift; - asic3_mmc_resources[0].end >>= asic->bus_shift; - - ret = mfd_add_devices(&pdev->dev, pdev->id, - &asic3_cell_ds1wm, 1, mem, asic->irq_base); - if (ret < 0) - goto out; - - if (mem_sdio && (irq >= 0)) { - ret = mfd_add_devices(&pdev->dev, pdev->id, - &asic3_cell_mmc, 1, mem_sdio, irq); - if (ret < 0) - goto out; - } - - if (pdata->leds) { - int i; - - for (i = 0; i < ASIC3_NUM_LEDS; ++i) { - asic3_cell_leds[i].platform_data = &pdata->leds[i]; - asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); - } - ret = mfd_add_devices(&pdev->dev, 0, - asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); - } - - out: - return ret; -} - -static void asic3_mfd_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - - mfd_remove_devices(&pdev->dev); - iounmap(asic->tmio_cnf); -} - -/* Core */ -static int __init asic3_probe(struct platform_device *pdev) -{ - struct asic3_platform_data *pdata = pdev->dev.platform_data; - struct asic3 *asic; - struct resource *mem; - unsigned long clksel; - int ret = 0; - - asic = kzalloc(sizeof(struct asic3), GFP_KERNEL); - if (asic == NULL) { - printk(KERN_ERR "kzalloc failed\n"); - return -ENOMEM; - } - - spin_lock_init(&asic->lock); - platform_set_drvdata(pdev, asic); - asic->dev = &pdev->dev; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - ret = -ENOMEM; - dev_err(asic->dev, "no MEM resource\n"); - goto out_free; - } - - asic->mapping = ioremap(mem->start, resource_size(mem)); - if (!asic->mapping) { - ret = -ENOMEM; - dev_err(asic->dev, "Couldn't ioremap\n"); - goto out_free; - } - - asic->irq_base = pdata->irq_base; - - /* calculate bus shift from mem resource */ - asic->bus_shift = 2 - (resource_size(mem) >> 12); - - clksel = 0; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel); - - ret = asic3_irq_probe(pdev); - if (ret < 0) { - dev_err(asic->dev, "Couldn't probe IRQs\n"); - goto out_unmap; - } - - asic->gpio.label = "asic3"; - asic->gpio.base = pdata->gpio_base; - asic->gpio.ngpio = ASIC3_NUM_GPIOS; - asic->gpio.get = asic3_gpio_get; - asic->gpio.set = asic3_gpio_set; - asic->gpio.direction_input = asic3_gpio_direction_input; - asic->gpio.direction_output = asic3_gpio_direction_output; - asic->gpio.to_irq = asic3_gpio_to_irq; - - ret = asic3_gpio_probe(pdev, - pdata->gpio_config, - pdata->gpio_config_num); - if (ret < 0) { - dev_err(asic->dev, "GPIO probe failed\n"); - goto out_irq; - } - - /* Making a per-device copy is only needed for the - * theoretical case of multiple ASIC3s on one board: - */ - memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init)); - - asic3_mfd_probe(pdev, pdata, mem); - - dev_info(asic->dev, "ASIC3 Core driver\n"); - - return 0; - - out_irq: - asic3_irq_remove(pdev); - - out_unmap: - iounmap(asic->mapping); - - out_free: - kfree(asic); - - return ret; -} - -static int __devexit asic3_remove(struct platform_device *pdev) -{ - int ret; - struct asic3 *asic = platform_get_drvdata(pdev); - - asic3_mfd_remove(pdev); - - ret = asic3_gpio_remove(pdev); - if (ret < 0) - return ret; - asic3_irq_remove(pdev); - - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0); - - iounmap(asic->mapping); - - kfree(asic); - - return 0; -} - -static void asic3_shutdown(struct platform_device *pdev) -{ -} - -static struct platform_driver asic3_device_driver = { - .driver = { - .name = "asic3", - }, - .remove = __devexit_p(asic3_remove), - .shutdown = asic3_shutdown, -}; - -static int __init asic3_init(void) -{ - int retval = 0; - retval = platform_driver_probe(&asic3_device_driver, asic3_probe); - return retval; -} - -subsys_initcall(asic3_init); diff --git a/ANDROID_3.4.5/drivers/mfd/cs5535-mfd.c b/ANDROID_3.4.5/drivers/mfd/cs5535-mfd.c deleted file mode 100644 index 315fef5d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/cs5535-mfd.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * cs5535-mfd.c - core MFD driver for CS5535/CS5536 southbridges - * - * The CS5535 and CS5536 has an ISA bridge on the PCI bus that is - * used for accessing GPIOs, MFGPTs, ACPI, etc. Each subdevice has - * an IO range that's specified in a single BAR. The BAR order is - * hardcoded in the CS553x specifications. - * - * Copyright (c) 2010 Andres Salomon <dilinger@queued.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/mfd/core.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <asm/olpc.h> - -#define DRV_NAME "cs5535-mfd" - -enum cs5535_mfd_bars { - SMB_BAR = 0, - GPIO_BAR = 1, - MFGPT_BAR = 2, - PMS_BAR = 4, - ACPI_BAR = 5, - NR_BARS, -}; - -static int cs5535_mfd_res_enable(struct platform_device *pdev) -{ - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); - return -EIO; - } - - if (!request_region(res->start, resource_size(res), DRV_NAME)) { - dev_err(&pdev->dev, "can't request region\n"); - return -EIO; - } - - return 0; -} - -static int cs5535_mfd_res_disable(struct platform_device *pdev) -{ - struct resource *res; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); - return -EIO; - } - - release_region(res->start, resource_size(res)); - return 0; -} - -static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; - -static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { - { - .id = SMB_BAR, - .name = "cs5535-smb", - .num_resources = 1, - .resources = &cs5535_mfd_resources[SMB_BAR], - }, - { - .id = GPIO_BAR, - .name = "cs5535-gpio", - .num_resources = 1, - .resources = &cs5535_mfd_resources[GPIO_BAR], - }, - { - .id = MFGPT_BAR, - .name = "cs5535-mfgpt", - .num_resources = 1, - .resources = &cs5535_mfd_resources[MFGPT_BAR], - }, - { - .id = PMS_BAR, - .name = "cs5535-pms", - .num_resources = 1, - .resources = &cs5535_mfd_resources[PMS_BAR], - - .enable = cs5535_mfd_res_enable, - .disable = cs5535_mfd_res_disable, - }, - { - .id = ACPI_BAR, - .name = "cs5535-acpi", - .num_resources = 1, - .resources = &cs5535_mfd_resources[ACPI_BAR], - - .enable = cs5535_mfd_res_enable, - .disable = cs5535_mfd_res_disable, - }, -}; - -#ifdef CONFIG_OLPC -static void __devinit cs5535_clone_olpc_cells(void) -{ - const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" }; - - if (!machine_is_olpc()) - return; - - mfd_clone_cell("cs5535-acpi", acpi_clones, ARRAY_SIZE(acpi_clones)); -} -#else -static void cs5535_clone_olpc_cells(void) { } -#endif - -static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int err, i; - - err = pci_enable_device(pdev); - if (err) - return err; - - /* fill in IO range for each cell; subdrivers handle the region */ - for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) { - int bar = cs5535_mfd_cells[i].id; - struct resource *r = &cs5535_mfd_resources[bar]; - - r->flags = IORESOURCE_IO; - r->start = pci_resource_start(pdev, bar); - r->end = pci_resource_end(pdev, bar); - - /* id is used for temporarily storing BAR; unset it now */ - cs5535_mfd_cells[i].id = 0; - } - - err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, - ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); - if (err) { - dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); - goto err_disable; - } - cs5535_clone_olpc_cells(); - - dev_info(&pdev->dev, "%zu devices registered.\n", - ARRAY_SIZE(cs5535_mfd_cells)); - - return 0; - -err_disable: - pci_disable_device(pdev); - return err; -} - -static void __devexit cs5535_mfd_remove(struct pci_dev *pdev) -{ - mfd_remove_devices(&pdev->dev); - pci_disable_device(pdev); -} - -static DEFINE_PCI_DEVICE_TABLE(cs5535_mfd_pci_tbl) = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); - -static struct pci_driver cs5535_mfd_driver = { - .name = DRV_NAME, - .id_table = cs5535_mfd_pci_tbl, - .probe = cs5535_mfd_probe, - .remove = __devexit_p(cs5535_mfd_remove), -}; - -static int __init cs5535_mfd_init(void) -{ - return pci_register_driver(&cs5535_mfd_driver); -} - -static void __exit cs5535_mfd_exit(void) -{ - pci_unregister_driver(&cs5535_mfd_driver); -} - -module_init(cs5535_mfd_init); -module_exit(cs5535_mfd_exit); - -MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); -MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/da903x.c b/ANDROID_3.4.5/drivers/mfd/da903x.c deleted file mode 100644 index 1924b857..00000000 --- a/ANDROID_3.4.5/drivers/mfd/da903x.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Base driver for Dialog Semiconductor DA9030/DA9034 - * - * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport <mike@compulab.co.il> - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao <eric.miao@marvell.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/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/mfd/da903x.h> -#include <linux/slab.h> - -#define DA9030_CHIP_ID 0x00 -#define DA9030_EVENT_A 0x01 -#define DA9030_EVENT_B 0x02 -#define DA9030_EVENT_C 0x03 -#define DA9030_STATUS 0x04 -#define DA9030_IRQ_MASK_A 0x05 -#define DA9030_IRQ_MASK_B 0x06 -#define DA9030_IRQ_MASK_C 0x07 -#define DA9030_SYS_CTRL_A 0x08 -#define DA9030_SYS_CTRL_B 0x09 -#define DA9030_FAULT_LOG 0x0a - -#define DA9034_CHIP_ID 0x00 -#define DA9034_EVENT_A 0x01 -#define DA9034_EVENT_B 0x02 -#define DA9034_EVENT_C 0x03 -#define DA9034_EVENT_D 0x04 -#define DA9034_STATUS_A 0x05 -#define DA9034_STATUS_B 0x06 -#define DA9034_IRQ_MASK_A 0x07 -#define DA9034_IRQ_MASK_B 0x08 -#define DA9034_IRQ_MASK_C 0x09 -#define DA9034_IRQ_MASK_D 0x0a -#define DA9034_SYS_CTRL_A 0x0b -#define DA9034_SYS_CTRL_B 0x0c -#define DA9034_FAULT_LOG 0x0d - -struct da903x_chip; - -struct da903x_chip_ops { - int (*init_chip)(struct da903x_chip *); - int (*unmask_events)(struct da903x_chip *, unsigned int events); - int (*mask_events)(struct da903x_chip *, unsigned int events); - int (*read_events)(struct da903x_chip *, unsigned int *events); - int (*read_status)(struct da903x_chip *, unsigned int *status); -}; - -struct da903x_chip { - struct i2c_client *client; - struct device *dev; - struct da903x_chip_ops *ops; - - int type; - uint32_t events_mask; - - struct mutex lock; - struct work_struct irq_work; - - struct blocking_notifier_head notifier_list; -}; - -static inline int __da903x_read(struct i2c_client *client, - int reg, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "failed reading at 0x%02x\n", reg); - return ret; - } - - *val = (uint8_t)ret; - return 0; -} - -static inline int __da903x_reads(struct i2c_client *client, int reg, - int len, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); - if (ret < 0) { - dev_err(&client->dev, "failed reading from 0x%02x\n", reg); - return ret; - } - return 0; -} - -static inline int __da903x_write(struct i2c_client *client, - int reg, uint8_t val) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, val); - if (ret < 0) { - dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", - val, reg); - return ret; - } - return 0; -} - -static inline int __da903x_writes(struct i2c_client *client, int reg, - int len, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); - if (ret < 0) { - dev_err(&client->dev, "failed writings to 0x%02x\n", reg); - return ret; - } - return 0; -} - -int da903x_register_notifier(struct device *dev, struct notifier_block *nb, - unsigned int events) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - - chip->ops->unmask_events(chip, events); - return blocking_notifier_chain_register(&chip->notifier_list, nb); -} -EXPORT_SYMBOL_GPL(da903x_register_notifier); - -int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb, - unsigned int events) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - - chip->ops->mask_events(chip, events); - return blocking_notifier_chain_unregister(&chip->notifier_list, nb); -} -EXPORT_SYMBOL_GPL(da903x_unregister_notifier); - -int da903x_write(struct device *dev, int reg, uint8_t val) -{ - return __da903x_write(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(da903x_write); - -int da903x_writes(struct device *dev, int reg, int len, uint8_t *val) -{ - return __da903x_writes(to_i2c_client(dev), reg, len, val); -} -EXPORT_SYMBOL_GPL(da903x_writes); - -int da903x_read(struct device *dev, int reg, uint8_t *val) -{ - return __da903x_read(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(da903x_read); - -int da903x_reads(struct device *dev, int reg, int len, uint8_t *val) -{ - return __da903x_reads(to_i2c_client(dev), reg, len, val); -} -EXPORT_SYMBOL_GPL(da903x_reads); - -int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&chip->lock); - - ret = __da903x_read(chip->client, reg, ®_val); - if (ret) - goto out; - - if ((reg_val & bit_mask) != bit_mask) { - reg_val |= bit_mask; - ret = __da903x_write(chip->client, reg, reg_val); - } -out: - mutex_unlock(&chip->lock); - return ret; -} -EXPORT_SYMBOL_GPL(da903x_set_bits); - -int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&chip->lock); - - ret = __da903x_read(chip->client, reg, ®_val); - if (ret) - goto out; - - if (reg_val & bit_mask) { - reg_val &= ~bit_mask; - ret = __da903x_write(chip->client, reg, reg_val); - } -out: - mutex_unlock(&chip->lock); - return ret; -} -EXPORT_SYMBOL_GPL(da903x_clr_bits); - -int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&chip->lock); - - ret = __da903x_read(chip->client, reg, ®_val); - if (ret) - goto out; - - if ((reg_val & mask) != val) { - reg_val = (reg_val & ~mask) | val; - ret = __da903x_write(chip->client, reg, reg_val); - } -out: - mutex_unlock(&chip->lock); - return ret; -} -EXPORT_SYMBOL_GPL(da903x_update); - -int da903x_query_status(struct device *dev, unsigned int sbits) -{ - struct da903x_chip *chip = dev_get_drvdata(dev); - unsigned int status = 0; - - chip->ops->read_status(chip, &status); - return ((status & sbits) == sbits); -} -EXPORT_SYMBOL(da903x_query_status); - -static int __devinit da9030_init_chip(struct da903x_chip *chip) -{ - uint8_t chip_id; - int err; - - err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id); - if (err) - return err; - - err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8); - if (err) - return err; - - dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id); - return 0; -} - -static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events) -{ - uint8_t v[3]; - - chip->events_mask &= ~events; - - v[0] = (chip->events_mask & 0xff); - v[1] = (chip->events_mask >> 8) & 0xff; - v[2] = (chip->events_mask >> 16) & 0xff; - - return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v); -} - -static int da9030_mask_events(struct da903x_chip *chip, unsigned int events) -{ - uint8_t v[3]; - - chip->events_mask |= events; - - v[0] = (chip->events_mask & 0xff); - v[1] = (chip->events_mask >> 8) & 0xff; - v[2] = (chip->events_mask >> 16) & 0xff; - - return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v); -} - -static int da9030_read_events(struct da903x_chip *chip, unsigned int *events) -{ - uint8_t v[3] = {0, 0, 0}; - int ret; - - ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v); - if (ret < 0) - return ret; - - *events = (v[2] << 16) | (v[1] << 8) | v[0]; - return 0; -} - -static int da9030_read_status(struct da903x_chip *chip, unsigned int *status) -{ - return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status); -} - -static int da9034_init_chip(struct da903x_chip *chip) -{ - uint8_t chip_id; - int err; - - err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id); - if (err) - return err; - - err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8); - if (err) - return err; - - /* avoid SRAM power off during sleep*/ - __da903x_write(chip->client, 0x10, 0x07); - __da903x_write(chip->client, 0x11, 0xff); - __da903x_write(chip->client, 0x12, 0xff); - - /* Enable the ONKEY power down functionality */ - __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20); - __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60); - - /* workaround to make LEDs work */ - __da903x_write(chip->client, 0x90, 0x01); - __da903x_write(chip->client, 0xB0, 0x08); - - /* make ADTV1 and SDTV1 effective */ - __da903x_write(chip->client, 0x20, 0x00); - - dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id); - return 0; -} - -static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events) -{ - uint8_t v[4]; - - chip->events_mask &= ~events; - - v[0] = (chip->events_mask & 0xff); - v[1] = (chip->events_mask >> 8) & 0xff; - v[2] = (chip->events_mask >> 16) & 0xff; - v[3] = (chip->events_mask >> 24) & 0xff; - - return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v); -} - -static int da9034_mask_events(struct da903x_chip *chip, unsigned int events) -{ - uint8_t v[4]; - - chip->events_mask |= events; - - v[0] = (chip->events_mask & 0xff); - v[1] = (chip->events_mask >> 8) & 0xff; - v[2] = (chip->events_mask >> 16) & 0xff; - v[3] = (chip->events_mask >> 24) & 0xff; - - return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v); -} - -static int da9034_read_events(struct da903x_chip *chip, unsigned int *events) -{ - uint8_t v[4] = {0, 0, 0, 0}; - int ret; - - ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v); - if (ret < 0) - return ret; - - *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0]; - return 0; -} - -static int da9034_read_status(struct da903x_chip *chip, unsigned int *status) -{ - uint8_t v[2] = {0, 0}; - int ret = 0; - - ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v); - if (ret) - return ret; - - *status = (v[1] << 8) | v[0]; - return 0; -} - -static void da903x_irq_work(struct work_struct *work) -{ - struct da903x_chip *chip = - container_of(work, struct da903x_chip, irq_work); - unsigned int events = 0; - - while (1) { - if (chip->ops->read_events(chip, &events)) - break; - - events &= ~chip->events_mask; - if (events == 0) - break; - - blocking_notifier_call_chain( - &chip->notifier_list, events, NULL); - } - enable_irq(chip->client->irq); -} - -static irqreturn_t da903x_irq_handler(int irq, void *data) -{ - struct da903x_chip *chip = data; - - disable_irq_nosync(irq); - (void)schedule_work(&chip->irq_work); - - return IRQ_HANDLED; -} - -static struct da903x_chip_ops da903x_ops[] = { - [0] = { - .init_chip = da9030_init_chip, - .unmask_events = da9030_unmask_events, - .mask_events = da9030_mask_events, - .read_events = da9030_read_events, - .read_status = da9030_read_status, - }, - [1] = { - .init_chip = da9034_init_chip, - .unmask_events = da9034_unmask_events, - .mask_events = da9034_mask_events, - .read_events = da9034_read_events, - .read_status = da9034_read_status, - } -}; - -static const struct i2c_device_id da903x_id_table[] = { - { "da9030", 0 }, - { "da9034", 1 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, da903x_id_table); - -static int __remove_subdev(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - -static int da903x_remove_subdevs(struct da903x_chip *chip) -{ - return device_for_each_child(chip->dev, NULL, __remove_subdev); -} - -static int __devinit da903x_add_subdevs(struct da903x_chip *chip, - struct da903x_platform_data *pdata) -{ - struct da903x_subdev_info *subdev; - struct platform_device *pdev; - int i, ret = 0; - - for (i = 0; i < pdata->num_subdevs; i++) { - subdev = &pdata->subdevs[i]; - - pdev = platform_device_alloc(subdev->name, subdev->id); - if (!pdev) { - ret = -ENOMEM; - goto failed; - } - - pdev->dev.parent = chip->dev; - pdev->dev.platform_data = subdev->platform_data; - - ret = platform_device_add(pdev); - if (ret) { - platform_device_put(pdev); - goto failed; - } - } - return 0; - -failed: - da903x_remove_subdevs(chip); - return ret; -} - -static int __devinit da903x_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct da903x_platform_data *pdata = client->dev.platform_data; - struct da903x_chip *chip; - unsigned int tmp; - int ret; - - chip = kzalloc(sizeof(struct da903x_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - - chip->client = client; - chip->dev = &client->dev; - chip->ops = &da903x_ops[id->driver_data]; - - mutex_init(&chip->lock); - INIT_WORK(&chip->irq_work, da903x_irq_work); - BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list); - - i2c_set_clientdata(client, chip); - - ret = chip->ops->init_chip(chip); - if (ret) - goto out_free_chip; - - /* mask and clear all IRQs */ - chip->events_mask = 0xffffffff; - chip->ops->mask_events(chip, chip->events_mask); - chip->ops->read_events(chip, &tmp); - - ret = request_irq(client->irq, da903x_irq_handler, - IRQF_TRIGGER_FALLING, - "da903x", chip); - if (ret) { - dev_err(&client->dev, "failed to request irq %d\n", - client->irq); - goto out_free_chip; - } - - ret = da903x_add_subdevs(chip, pdata); - if (ret) - goto out_free_irq; - - return 0; - -out_free_irq: - free_irq(client->irq, chip); -out_free_chip: - kfree(chip); - return ret; -} - -static int __devexit da903x_remove(struct i2c_client *client) -{ - struct da903x_chip *chip = i2c_get_clientdata(client); - - da903x_remove_subdevs(chip); - free_irq(client->irq, chip); - kfree(chip); - return 0; -} - -static struct i2c_driver da903x_driver = { - .driver = { - .name = "da903x", - .owner = THIS_MODULE, - }, - .probe = da903x_probe, - .remove = __devexit_p(da903x_remove), - .id_table = da903x_id_table, -}; - -static int __init da903x_init(void) -{ - return i2c_add_driver(&da903x_driver); -} -subsys_initcall(da903x_init); - -static void __exit da903x_exit(void) -{ - i2c_del_driver(&da903x_driver); -} -module_exit(da903x_exit); - -MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034"); -MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" - "Mike Rapoport <mike@compulab.co.il>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/da9052-core.c b/ANDROID_3.4.5/drivers/mfd/da9052-core.c deleted file mode 100644 index 7ff313fe..00000000 --- a/ANDROID_3.4.5/drivers/mfd/da9052-core.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Device access for Dialog DA9052 PMICs. - * - * Copyright(c) 2011 Dialog Semiconductor Ltd. - * - * Author: David Dajun Chen <dchen@diasemi.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mfd/core.h> -#include <linux/slab.h> -#include <linux/module.h> - -#include <linux/mfd/da9052/da9052.h> -#include <linux/mfd/da9052/pdata.h> -#include <linux/mfd/da9052/reg.h> - -#define DA9052_NUM_IRQ_REGS 4 -#define DA9052_IRQ_MASK_POS_1 0x01 -#define DA9052_IRQ_MASK_POS_2 0x02 -#define DA9052_IRQ_MASK_POS_3 0x04 -#define DA9052_IRQ_MASK_POS_4 0x08 -#define DA9052_IRQ_MASK_POS_5 0x10 -#define DA9052_IRQ_MASK_POS_6 0x20 -#define DA9052_IRQ_MASK_POS_7 0x40 -#define DA9052_IRQ_MASK_POS_8 0x80 - -static bool da9052_reg_readable(struct device *dev, unsigned int reg) -{ - switch (reg) { - case DA9052_PAGE0_CON_REG: - case DA9052_STATUS_A_REG: - case DA9052_STATUS_B_REG: - case DA9052_STATUS_C_REG: - case DA9052_STATUS_D_REG: - case DA9052_EVENT_A_REG: - case DA9052_EVENT_B_REG: - case DA9052_EVENT_C_REG: - case DA9052_EVENT_D_REG: - case DA9052_FAULTLOG_REG: - case DA9052_IRQ_MASK_A_REG: - case DA9052_IRQ_MASK_B_REG: - case DA9052_IRQ_MASK_C_REG: - case DA9052_IRQ_MASK_D_REG: - case DA9052_CONTROL_A_REG: - case DA9052_CONTROL_B_REG: - case DA9052_CONTROL_C_REG: - case DA9052_CONTROL_D_REG: - case DA9052_PDDIS_REG: - case DA9052_INTERFACE_REG: - case DA9052_RESET_REG: - case DA9052_GPIO_0_1_REG: - case DA9052_GPIO_2_3_REG: - case DA9052_GPIO_4_5_REG: - case DA9052_GPIO_6_7_REG: - case DA9052_GPIO_14_15_REG: - case DA9052_ID_0_1_REG: - case DA9052_ID_2_3_REG: - case DA9052_ID_4_5_REG: - case DA9052_ID_6_7_REG: - case DA9052_ID_8_9_REG: - case DA9052_ID_10_11_REG: - case DA9052_ID_12_13_REG: - case DA9052_ID_14_15_REG: - case DA9052_ID_16_17_REG: - case DA9052_ID_18_19_REG: - case DA9052_ID_20_21_REG: - case DA9052_SEQ_STATUS_REG: - case DA9052_SEQ_A_REG: - case DA9052_SEQ_B_REG: - case DA9052_SEQ_TIMER_REG: - case DA9052_BUCKA_REG: - case DA9052_BUCKB_REG: - case DA9052_BUCKCORE_REG: - case DA9052_BUCKPRO_REG: - case DA9052_BUCKMEM_REG: - case DA9052_BUCKPERI_REG: - case DA9052_LDO1_REG: - case DA9052_LDO2_REG: - case DA9052_LDO3_REG: - case DA9052_LDO4_REG: - case DA9052_LDO5_REG: - case DA9052_LDO6_REG: - case DA9052_LDO7_REG: - case DA9052_LDO8_REG: - case DA9052_LDO9_REG: - case DA9052_LDO10_REG: - case DA9052_SUPPLY_REG: - case DA9052_PULLDOWN_REG: - case DA9052_CHGBUCK_REG: - case DA9052_WAITCONT_REG: - case DA9052_ISET_REG: - case DA9052_BATCHG_REG: - case DA9052_CHG_CONT_REG: - case DA9052_INPUT_CONT_REG: - case DA9052_CHG_TIME_REG: - case DA9052_BBAT_CONT_REG: - case DA9052_BOOST_REG: - case DA9052_LED_CONT_REG: - case DA9052_LEDMIN123_REG: - case DA9052_LED1_CONF_REG: - case DA9052_LED2_CONF_REG: - case DA9052_LED3_CONF_REG: - case DA9052_LED1CONT_REG: - case DA9052_LED2CONT_REG: - case DA9052_LED3CONT_REG: - case DA9052_LED_CONT_4_REG: - case DA9052_LED_CONT_5_REG: - case DA9052_ADC_MAN_REG: - case DA9052_ADC_CONT_REG: - case DA9052_ADC_RES_L_REG: - case DA9052_ADC_RES_H_REG: - case DA9052_VDD_RES_REG: - case DA9052_VDD_MON_REG: - case DA9052_ICHG_AV_REG: - case DA9052_ICHG_THD_REG: - case DA9052_ICHG_END_REG: - case DA9052_TBAT_RES_REG: - case DA9052_TBAT_HIGHP_REG: - case DA9052_TBAT_HIGHN_REG: - case DA9052_TBAT_LOW_REG: - case DA9052_T_OFFSET_REG: - case DA9052_ADCIN4_RES_REG: - case DA9052_AUTO4_HIGH_REG: - case DA9052_AUTO4_LOW_REG: - case DA9052_ADCIN5_RES_REG: - case DA9052_AUTO5_HIGH_REG: - case DA9052_AUTO5_LOW_REG: - case DA9052_ADCIN6_RES_REG: - case DA9052_AUTO6_HIGH_REG: - case DA9052_AUTO6_LOW_REG: - case DA9052_TJUNC_RES_REG: - case DA9052_TSI_CONT_A_REG: - case DA9052_TSI_CONT_B_REG: - case DA9052_TSI_X_MSB_REG: - case DA9052_TSI_Y_MSB_REG: - case DA9052_TSI_LSB_REG: - case DA9052_TSI_Z_MSB_REG: - case DA9052_COUNT_S_REG: - case DA9052_COUNT_MI_REG: - case DA9052_COUNT_H_REG: - case DA9052_COUNT_D_REG: - case DA9052_COUNT_MO_REG: - case DA9052_COUNT_Y_REG: - case DA9052_ALARM_MI_REG: - case DA9052_ALARM_H_REG: - case DA9052_ALARM_D_REG: - case DA9052_ALARM_MO_REG: - case DA9052_ALARM_Y_REG: - case DA9052_SECOND_A_REG: - case DA9052_SECOND_B_REG: - case DA9052_SECOND_C_REG: - case DA9052_SECOND_D_REG: - case DA9052_PAGE1_CON_REG: - return true; - default: - return false; - } -} - -static bool da9052_reg_writeable(struct device *dev, unsigned int reg) -{ - switch (reg) { - case DA9052_PAGE0_CON_REG: - case DA9052_EVENT_A_REG: - case DA9052_EVENT_B_REG: - case DA9052_EVENT_C_REG: - case DA9052_EVENT_D_REG: - case DA9052_IRQ_MASK_A_REG: - case DA9052_IRQ_MASK_B_REG: - case DA9052_IRQ_MASK_C_REG: - case DA9052_IRQ_MASK_D_REG: - case DA9052_CONTROL_A_REG: - case DA9052_CONTROL_B_REG: - case DA9052_CONTROL_C_REG: - case DA9052_CONTROL_D_REG: - case DA9052_PDDIS_REG: - case DA9052_RESET_REG: - case DA9052_GPIO_0_1_REG: - case DA9052_GPIO_2_3_REG: - case DA9052_GPIO_4_5_REG: - case DA9052_GPIO_6_7_REG: - case DA9052_GPIO_14_15_REG: - case DA9052_ID_0_1_REG: - case DA9052_ID_2_3_REG: - case DA9052_ID_4_5_REG: - case DA9052_ID_6_7_REG: - case DA9052_ID_8_9_REG: - case DA9052_ID_10_11_REG: - case DA9052_ID_12_13_REG: - case DA9052_ID_14_15_REG: - case DA9052_ID_16_17_REG: - case DA9052_ID_18_19_REG: - case DA9052_ID_20_21_REG: - case DA9052_SEQ_STATUS_REG: - case DA9052_SEQ_A_REG: - case DA9052_SEQ_B_REG: - case DA9052_SEQ_TIMER_REG: - case DA9052_BUCKA_REG: - case DA9052_BUCKB_REG: - case DA9052_BUCKCORE_REG: - case DA9052_BUCKPRO_REG: - case DA9052_BUCKMEM_REG: - case DA9052_BUCKPERI_REG: - case DA9052_LDO1_REG: - case DA9052_LDO2_REG: - case DA9052_LDO3_REG: - case DA9052_LDO4_REG: - case DA9052_LDO5_REG: - case DA9052_LDO6_REG: - case DA9052_LDO7_REG: - case DA9052_LDO8_REG: - case DA9052_LDO9_REG: - case DA9052_LDO10_REG: - case DA9052_SUPPLY_REG: - case DA9052_PULLDOWN_REG: - case DA9052_CHGBUCK_REG: - case DA9052_WAITCONT_REG: - case DA9052_ISET_REG: - case DA9052_BATCHG_REG: - case DA9052_CHG_CONT_REG: - case DA9052_INPUT_CONT_REG: - case DA9052_BBAT_CONT_REG: - case DA9052_BOOST_REG: - case DA9052_LED_CONT_REG: - case DA9052_LEDMIN123_REG: - case DA9052_LED1_CONF_REG: - case DA9052_LED2_CONF_REG: - case DA9052_LED3_CONF_REG: - case DA9052_LED1CONT_REG: - case DA9052_LED2CONT_REG: - case DA9052_LED3CONT_REG: - case DA9052_LED_CONT_4_REG: - case DA9052_LED_CONT_5_REG: - case DA9052_ADC_MAN_REG: - case DA9052_ADC_CONT_REG: - case DA9052_ADC_RES_L_REG: - case DA9052_ADC_RES_H_REG: - case DA9052_VDD_RES_REG: - case DA9052_VDD_MON_REG: - case DA9052_ICHG_THD_REG: - case DA9052_ICHG_END_REG: - case DA9052_TBAT_HIGHP_REG: - case DA9052_TBAT_HIGHN_REG: - case DA9052_TBAT_LOW_REG: - case DA9052_T_OFFSET_REG: - case DA9052_AUTO4_HIGH_REG: - case DA9052_AUTO4_LOW_REG: - case DA9052_AUTO5_HIGH_REG: - case DA9052_AUTO5_LOW_REG: - case DA9052_AUTO6_HIGH_REG: - case DA9052_AUTO6_LOW_REG: - case DA9052_TSI_CONT_A_REG: - case DA9052_TSI_CONT_B_REG: - case DA9052_COUNT_S_REG: - case DA9052_COUNT_MI_REG: - case DA9052_COUNT_H_REG: - case DA9052_COUNT_D_REG: - case DA9052_COUNT_MO_REG: - case DA9052_COUNT_Y_REG: - case DA9052_ALARM_MI_REG: - case DA9052_ALARM_H_REG: - case DA9052_ALARM_D_REG: - case DA9052_ALARM_MO_REG: - case DA9052_ALARM_Y_REG: - case DA9052_PAGE1_CON_REG: - return true; - default: - return false; - } -} - -static bool da9052_reg_volatile(struct device *dev, unsigned int reg) -{ - switch (reg) { - case DA9052_STATUS_A_REG: - case DA9052_STATUS_B_REG: - case DA9052_STATUS_C_REG: - case DA9052_STATUS_D_REG: - case DA9052_EVENT_A_REG: - case DA9052_EVENT_B_REG: - case DA9052_EVENT_C_REG: - case DA9052_EVENT_D_REG: - case DA9052_FAULTLOG_REG: - case DA9052_CHG_TIME_REG: - case DA9052_ADC_RES_L_REG: - case DA9052_ADC_RES_H_REG: - case DA9052_VDD_RES_REG: - case DA9052_ICHG_AV_REG: - case DA9052_TBAT_RES_REG: - case DA9052_ADCIN4_RES_REG: - case DA9052_ADCIN5_RES_REG: - case DA9052_ADCIN6_RES_REG: - case DA9052_TJUNC_RES_REG: - case DA9052_TSI_X_MSB_REG: - case DA9052_TSI_Y_MSB_REG: - case DA9052_TSI_LSB_REG: - case DA9052_TSI_Z_MSB_REG: - case DA9052_COUNT_S_REG: - case DA9052_COUNT_MI_REG: - case DA9052_COUNT_H_REG: - case DA9052_COUNT_D_REG: - case DA9052_COUNT_MO_REG: - case DA9052_COUNT_Y_REG: - case DA9052_ALARM_MI_REG: - return true; - default: - return false; - } -} - -static struct resource da9052_rtc_resource = { - .name = "ALM", - .start = DA9052_IRQ_ALARM, - .end = DA9052_IRQ_ALARM, - .flags = IORESOURCE_IRQ, -}; - -static struct resource da9052_onkey_resource = { - .name = "ONKEY", - .start = DA9052_IRQ_NONKEY, - .end = DA9052_IRQ_NONKEY, - .flags = IORESOURCE_IRQ, -}; - -static struct resource da9052_bat_resources[] = { - { - .name = "BATT TEMP", - .start = DA9052_IRQ_TBAT, - .end = DA9052_IRQ_TBAT, - .flags = IORESOURCE_IRQ, - }, - { - .name = "DCIN DET", - .start = DA9052_IRQ_DCIN, - .end = DA9052_IRQ_DCIN, - .flags = IORESOURCE_IRQ, - }, - { - .name = "DCIN REM", - .start = DA9052_IRQ_DCINREM, - .end = DA9052_IRQ_DCINREM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS DET", - .start = DA9052_IRQ_VBUS, - .end = DA9052_IRQ_VBUS, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS REM", - .start = DA9052_IRQ_VBUSREM, - .end = DA9052_IRQ_VBUSREM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG END", - .start = DA9052_IRQ_CHGEND, - .end = DA9052_IRQ_CHGEND, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource da9052_tsi_resources[] = { - { - .name = "PENDWN", - .start = DA9052_IRQ_PENDOWN, - .end = DA9052_IRQ_PENDOWN, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TSIRDY", - .start = DA9052_IRQ_TSIREADY, - .end = DA9052_IRQ_TSIREADY, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell __devinitdata da9052_subdev_info[] = { - { - .name = "da9052-regulator", - .id = 1, - }, - { - .name = "da9052-regulator", - .id = 2, - }, - { - .name = "da9052-regulator", - .id = 3, - }, - { - .name = "da9052-regulator", - .id = 4, - }, - { - .name = "da9052-regulator", - .id = 5, - }, - { - .name = "da9052-regulator", - .id = 6, - }, - { - .name = "da9052-regulator", - .id = 7, - }, - { - .name = "da9052-regulator", - .id = 8, - }, - { - .name = "da9052-regulator", - .id = 9, - }, - { - .name = "da9052-regulator", - .id = 10, - }, - { - .name = "da9052-regulator", - .id = 11, - }, - { - .name = "da9052-regulator", - .id = 12, - }, - { - .name = "da9052-regulator", - .id = 13, - }, - { - .name = "da9052-regulator", - .id = 14, - }, - { - .name = "da9052-onkey", - .resources = &da9052_onkey_resource, - .num_resources = 1, - }, - { - .name = "da9052-rtc", - .resources = &da9052_rtc_resource, - .num_resources = 1, - }, - { - .name = "da9052-gpio", - }, - { - .name = "da9052-hwmon", - }, - { - .name = "da9052-leds", - }, - { - .name = "da9052-wled1", - }, - { - .name = "da9052-wled2", - }, - { - .name = "da9052-wled3", - }, - { - .name = "da9052-tsi", - .resources = da9052_tsi_resources, - .num_resources = ARRAY_SIZE(da9052_tsi_resources), - }, - { - .name = "da9052-bat", - .resources = da9052_bat_resources, - .num_resources = ARRAY_SIZE(da9052_bat_resources), - }, - { - .name = "da9052-watchdog", - }, -}; - -static struct regmap_irq da9052_irqs[] = { - [DA9052_IRQ_DCIN] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_1, - }, - [DA9052_IRQ_VBUS] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_2, - }, - [DA9052_IRQ_DCINREM] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_3, - }, - [DA9052_IRQ_VBUSREM] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_4, - }, - [DA9052_IRQ_VDDLOW] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_5, - }, - [DA9052_IRQ_ALARM] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_6, - }, - [DA9052_IRQ_SEQRDY] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_7, - }, - [DA9052_IRQ_COMP1V2] = { - .reg_offset = 0, - .mask = DA9052_IRQ_MASK_POS_8, - }, - [DA9052_IRQ_NONKEY] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_1, - }, - [DA9052_IRQ_IDFLOAT] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_2, - }, - [DA9052_IRQ_IDGND] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_3, - }, - [DA9052_IRQ_CHGEND] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_4, - }, - [DA9052_IRQ_TBAT] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_5, - }, - [DA9052_IRQ_ADC_EOM] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_6, - }, - [DA9052_IRQ_PENDOWN] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_7, - }, - [DA9052_IRQ_TSIREADY] = { - .reg_offset = 1, - .mask = DA9052_IRQ_MASK_POS_8, - }, - [DA9052_IRQ_GPI0] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_1, - }, - [DA9052_IRQ_GPI1] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_2, - }, - [DA9052_IRQ_GPI2] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_3, - }, - [DA9052_IRQ_GPI3] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_4, - }, - [DA9052_IRQ_GPI4] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_5, - }, - [DA9052_IRQ_GPI5] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_6, - }, - [DA9052_IRQ_GPI6] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_7, - }, - [DA9052_IRQ_GPI7] = { - .reg_offset = 2, - .mask = DA9052_IRQ_MASK_POS_8, - }, - [DA9052_IRQ_GPI8] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_1, - }, - [DA9052_IRQ_GPI9] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_2, - }, - [DA9052_IRQ_GPI10] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_3, - }, - [DA9052_IRQ_GPI11] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_4, - }, - [DA9052_IRQ_GPI12] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_5, - }, - [DA9052_IRQ_GPI13] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_6, - }, - [DA9052_IRQ_GPI14] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_7, - }, - [DA9052_IRQ_GPI15] = { - .reg_offset = 3, - .mask = DA9052_IRQ_MASK_POS_8, - }, -}; - -static struct regmap_irq_chip da9052_regmap_irq_chip = { - .name = "da9052_irq", - .status_base = DA9052_EVENT_A_REG, - .mask_base = DA9052_IRQ_MASK_A_REG, - .ack_base = DA9052_EVENT_A_REG, - .num_regs = DA9052_NUM_IRQ_REGS, - .irqs = da9052_irqs, - .num_irqs = ARRAY_SIZE(da9052_irqs), -}; - -struct regmap_config da9052_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - - .cache_type = REGCACHE_RBTREE, - - .max_register = DA9052_PAGE1_CON_REG, - .readable_reg = da9052_reg_readable, - .writeable_reg = da9052_reg_writeable, - .volatile_reg = da9052_reg_volatile, -}; -EXPORT_SYMBOL_GPL(da9052_regmap_config); - -int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) -{ - struct da9052_pdata *pdata = da9052->dev->platform_data; - struct irq_desc *desc; - int ret; - - if (pdata && pdata->init != NULL) - pdata->init(da9052); - - da9052->chip_id = chip_id; - - if (!pdata || !pdata->irq_base) - da9052->irq_base = -1; - else - da9052->irq_base = pdata->irq_base; - - ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - da9052->irq_base, &da9052_regmap_irq_chip, - NULL); - if (ret < 0) - goto regmap_err; - - desc = irq_to_desc(da9052->chip_irq); - da9052->irq_base = regmap_irq_chip_get_base(desc->action->dev_id); - - ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, - ARRAY_SIZE(da9052_subdev_info), NULL, 0); - if (ret) - goto err; - - return 0; - -err: - mfd_remove_devices(da9052->dev); -regmap_err: - return ret; -} - -void da9052_device_exit(struct da9052 *da9052) -{ - regmap_del_irq_chip(da9052->chip_irq, - irq_get_irq_data(da9052->irq_base)->chip_data); - mfd_remove_devices(da9052->dev); -} - -MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); -MODULE_DESCRIPTION("DA9052 MFD Core"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/da9052-i2c.c b/ANDROID_3.4.5/drivers/mfd/da9052-i2c.c deleted file mode 100644 index 36b88e39..00000000 --- a/ANDROID_3.4.5/drivers/mfd/da9052-i2c.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * I2C access for DA9052 PMICs. - * - * Copyright(c) 2011 Dialog Semiconductor Ltd. - * - * Author: David Dajun Chen <dchen@diasemi.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/input.h> -#include <linux/mfd/core.h> -#include <linux/i2c.h> -#include <linux/err.h> - -#include <linux/mfd/da9052/da9052.h> -#include <linux/mfd/da9052/reg.h> - -static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) -{ - int reg_val, ret; - - ret = regmap_read(da9052->regmap, DA9052_CONTROL_B_REG, ®_val); - if (ret < 0) - return ret; - - if (reg_val & DA9052_CONTROL_B_WRITEMODE) { - reg_val &= ~DA9052_CONTROL_B_WRITEMODE; - ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG, - reg_val); - if (ret < 0) - return ret; - } - - return 0; -} - -static int __devinit da9052_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct da9052 *da9052; - int ret; - - da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); - if (!da9052) - return -ENOMEM; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", - __func__); - ret = -ENODEV; - goto err; - } - - da9052->dev = &client->dev; - da9052->chip_irq = client->irq; - - i2c_set_clientdata(client, da9052); - - da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config); - if (IS_ERR(da9052->regmap)) { - ret = PTR_ERR(da9052->regmap); - dev_err(&client->dev, "Failed to allocate register map: %d\n", - ret); - goto err; - } - - ret = da9052_i2c_enable_multiwrite(da9052); - if (ret < 0) - goto err_regmap; - - ret = da9052_device_init(da9052, id->driver_data); - if (ret != 0) - goto err_regmap; - - return 0; - -err_regmap: - regmap_exit(da9052->regmap); -err: - kfree(da9052); - return ret; -} - -static int __devexit da9052_i2c_remove(struct i2c_client *client) -{ - struct da9052 *da9052 = i2c_get_clientdata(client); - - da9052_device_exit(da9052); - regmap_exit(da9052->regmap); - kfree(da9052); - - return 0; -} - -static struct i2c_device_id da9052_i2c_id[] = { - {"da9052", DA9052}, - {"da9053-aa", DA9053_AA}, - {"da9053-ba", DA9053_BA}, - {"da9053-bb", DA9053_BB}, - {} -}; - -static struct i2c_driver da9052_i2c_driver = { - .probe = da9052_i2c_probe, - .remove = __devexit_p(da9052_i2c_remove), - .id_table = da9052_i2c_id, - .driver = { - .name = "da9052", - .owner = THIS_MODULE, - }, -}; - -static int __init da9052_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&da9052_i2c_driver); - if (ret != 0) { - pr_err("DA9052 I2C registration failed %d\n", ret); - return ret; - } - - return 0; -} -subsys_initcall(da9052_i2c_init); - -static void __exit da9052_i2c_exit(void) -{ - i2c_del_driver(&da9052_i2c_driver); -} -module_exit(da9052_i2c_exit); - -MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); -MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/da9052-spi.c b/ANDROID_3.4.5/drivers/mfd/da9052-spi.c deleted file mode 100644 index 6faf149e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/da9052-spi.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SPI access for Dialog DA9052 PMICs. - * - * Copyright(c) 2011 Dialog Semiconductor Ltd. - * - * Author: David Dajun Chen <dchen@diasemi.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/input.h> -#include <linux/mfd/core.h> -#include <linux/spi/spi.h> -#include <linux/err.h> - -#include <linux/mfd/da9052/da9052.h> - -static int __devinit da9052_spi_probe(struct spi_device *spi) -{ - int ret; - const struct spi_device_id *id = spi_get_device_id(spi); - struct da9052 *da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); - - if (!da9052) - return -ENOMEM; - - spi->mode = SPI_MODE_0 | SPI_CPOL; - spi->bits_per_word = 8; - spi_setup(spi); - - da9052->dev = &spi->dev; - da9052->chip_irq = spi->irq; - - dev_set_drvdata(&spi->dev, da9052); - - da9052_regmap_config.read_flag_mask = 1; - da9052_regmap_config.write_flag_mask = 0; - - da9052->regmap = regmap_init_spi(spi, &da9052_regmap_config); - if (IS_ERR(da9052->regmap)) { - ret = PTR_ERR(da9052->regmap); - dev_err(&spi->dev, "Failed to allocate register map: %d\n", - ret); - goto err; - } - - ret = da9052_device_init(da9052, id->driver_data); - if (ret != 0) - goto err_regmap; - - return 0; - -err_regmap: - regmap_exit(da9052->regmap); -err: - kfree(da9052); - return ret; -} - -static int __devexit da9052_spi_remove(struct spi_device *spi) -{ - struct da9052 *da9052 = dev_get_drvdata(&spi->dev); - - da9052_device_exit(da9052); - regmap_exit(da9052->regmap); - kfree(da9052); - - return 0; -} - -static struct spi_device_id da9052_spi_id[] = { - {"da9052", DA9052}, - {"da9053-aa", DA9053_AA}, - {"da9053-ba", DA9053_BA}, - {"da9053-bb", DA9053_BB}, - {} -}; - -static struct spi_driver da9052_spi_driver = { - .probe = da9052_spi_probe, - .remove = __devexit_p(da9052_spi_remove), - .id_table = da9052_spi_id, - .driver = { - .name = "da9052", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, -}; - -static int __init da9052_spi_init(void) -{ - int ret; - - ret = spi_register_driver(&da9052_spi_driver); - if (ret != 0) { - pr_err("Failed to register DA9052 SPI driver, %d\n", ret); - return ret; - } - - return 0; -} -subsys_initcall(da9052_spi_init); - -static void __exit da9052_spi_exit(void) -{ - spi_unregister_driver(&da9052_spi_driver); -} -module_exit(da9052_spi_exit); - -MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); -MODULE_DESCRIPTION("SPI driver for Dialog DA9052 PMIC"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/davinci_voicecodec.c b/ANDROID_3.4.5/drivers/mfd/davinci_voicecodec.c deleted file mode 100644 index 4e2af2cb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/davinci_voicecodec.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * DaVinci Voice Codec Core Interface for TI platforms - * - * Copyright (C) 2010 Texas Instruments, Inc - * - * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/clk.h> - -#include <sound/pcm.h> - -#include <linux/mfd/davinci_voicecodec.h> - -u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg) -{ - return __raw_readl(davinci_vc->base + reg); -} - -void davinci_vc_write(struct davinci_vc *davinci_vc, - int reg, u32 val) -{ - __raw_writel(val, davinci_vc->base + reg); -} - -static int __init davinci_vc_probe(struct platform_device *pdev) -{ - struct davinci_vc *davinci_vc; - struct resource *res, *mem; - struct mfd_cell *cell = NULL; - int ret; - - davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL); - if (!davinci_vc) { - dev_dbg(&pdev->dev, - "could not allocate memory for private data\n"); - return -ENOMEM; - } - - davinci_vc->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(davinci_vc->clk)) { - dev_dbg(&pdev->dev, - "could not get the clock for voice codec\n"); - ret = -ENODEV; - goto fail1; - } - clk_enable(davinci_vc->clk); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mem resource\n"); - ret = -ENODEV; - goto fail2; - } - - davinci_vc->pbase = res->start; - davinci_vc->base_size = resource_size(res); - - mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size, - pdev->name); - if (!mem) { - dev_err(&pdev->dev, "VCIF region already claimed\n"); - ret = -EBUSY; - goto fail2; - } - - davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size); - if (!davinci_vc->base) { - dev_err(&pdev->dev, "can't ioremap mem resource.\n"); - ret = -ENOMEM; - goto fail3; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "no DMA resource\n"); - ret = -ENXIO; - goto fail4; - } - - davinci_vc->davinci_vcif.dma_tx_channel = res->start; - davinci_vc->davinci_vcif.dma_tx_addr = - (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "no DMA resource\n"); - ret = -ENXIO; - goto fail4; - } - - davinci_vc->davinci_vcif.dma_rx_channel = res->start; - davinci_vc->davinci_vcif.dma_rx_addr = - (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); - - davinci_vc->dev = &pdev->dev; - davinci_vc->pdev = pdev; - - /* Voice codec interface client */ - cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; - cell->name = "davinci-vcif"; - cell->platform_data = davinci_vc; - cell->pdata_size = sizeof(*davinci_vc); - - /* Voice codec CQ93VC client */ - cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; - cell->name = "cq93vc-codec"; - cell->platform_data = davinci_vc; - cell->pdata_size = sizeof(*davinci_vc); - - ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, - DAVINCI_VC_CELLS, NULL, 0); - if (ret != 0) { - dev_err(&pdev->dev, "fail to register client devices\n"); - goto fail4; - } - - return 0; - -fail4: - iounmap(davinci_vc->base); -fail3: - release_mem_region(davinci_vc->pbase, davinci_vc->base_size); -fail2: - clk_disable(davinci_vc->clk); - clk_put(davinci_vc->clk); - davinci_vc->clk = NULL; -fail1: - kfree(davinci_vc); - - return ret; -} - -static int __devexit davinci_vc_remove(struct platform_device *pdev) -{ - struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); - - mfd_remove_devices(&pdev->dev); - - iounmap(davinci_vc->base); - release_mem_region(davinci_vc->pbase, davinci_vc->base_size); - - clk_disable(davinci_vc->clk); - clk_put(davinci_vc->clk); - davinci_vc->clk = NULL; - - kfree(davinci_vc); - - return 0; -} - -static struct platform_driver davinci_vc_driver = { - .driver = { - .name = "davinci_voicecodec", - .owner = THIS_MODULE, - }, - .remove = __devexit_p(davinci_vc_remove), -}; - -static int __init davinci_vc_init(void) -{ - return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe); -} -module_init(davinci_vc_init); - -static void __exit davinci_vc_exit(void) -{ - platform_driver_unregister(&davinci_vc_driver); -} -module_exit(davinci_vc_exit); - -MODULE_AUTHOR("Miguel Aguilar"); -MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/db5500-prcmu.c b/ANDROID_3.4.5/drivers/mfd/db5500-prcmu.c deleted file mode 100644 index bb115b2f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/db5500-prcmu.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> - * - * U5500 PRCM Unit interface driver - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/completion.h> -#include <linux/irq.h> -#include <linux/jiffies.h> -#include <linux/bitops.h> -#include <linux/interrupt.h> -#include <linux/mfd/dbx500-prcmu.h> -#include <mach/hardware.h> -#include <mach/irqs.h> -#include <mach/db5500-regs.h> -#include "dbx500-prcmu-regs.h" - -#define _PRCM_MB_HEADER (tcdm_base + 0xFE8) -#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) -#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1) -#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2) -#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3) -#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4) -#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5) -#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6) -#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7) -#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8) -#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9) -#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa) -#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb) -#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc) -#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd) -#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe) -#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf) - -/* Req Mailboxes */ -#define PRCM_REQ_MB0 (tcdm_base + 0xFD8) -#define PRCM_REQ_MB1 (tcdm_base + 0xFCC) -#define PRCM_REQ_MB2 (tcdm_base + 0xFC4) -#define PRCM_REQ_MB3 (tcdm_base + 0xFC0) -#define PRCM_REQ_MB4 (tcdm_base + 0xF98) -#define PRCM_REQ_MB5 (tcdm_base + 0xF90) -#define PRCM_REQ_MB6 (tcdm_base + 0xF8C) -#define PRCM_REQ_MB7 (tcdm_base + 0xF84) - -/* Ack Mailboxes */ -#define PRCM_ACK_MB0 (tcdm_base + 0xF38) -#define PRCM_ACK_MB1 (tcdm_base + 0xF30) -#define PRCM_ACK_MB2 (tcdm_base + 0xF24) -#define PRCM_ACK_MB3 (tcdm_base + 0xF20) -#define PRCM_ACK_MB4 (tcdm_base + 0xF1C) -#define PRCM_ACK_MB5 (tcdm_base + 0xF14) -#define PRCM_ACK_MB6 (tcdm_base + 0xF0C) -#define PRCM_ACK_MB7 (tcdm_base + 0xF08) - -enum mb_return_code { - RC_SUCCESS, - RC_FAIL, -}; - -/* Mailbox 0 headers. */ -enum mb0_header { - /* request */ - RMB0H_PWR_STATE_TRANS = 1, - RMB0H_WAKE_UP_CFG, - RMB0H_RD_WAKE_UP_ACK, - /* acknowledge */ - AMB0H_WAKE_UP = 1, -}; - -/* Mailbox 5 headers. */ -enum mb5_header { - MB5H_I2C_WRITE = 1, - MB5H_I2C_READ, -}; - -/* Request mailbox 5 fields. */ -#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0) -#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1) -#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2) -#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4) - -/* Acknowledge mailbox 5 fields. */ -#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0) -#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4) - -#define NUM_MB 8 -#define MBOX_BIT BIT -#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) - -/* -* Used by MCDE to setup all necessary PRCMU registers -*/ -#define PRCMU_RESET_DSIPLL 0x00004000 -#define PRCMU_UNCLAMP_DSIPLL 0x00400800 - -/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/ -#define PRCMU_DSI_CLOCK_SETTING 0x00000128 -/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ -#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 -#define PRCMU_PLLDSI_FREQ_SETTING 0x00020121 -#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 -#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201 -#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 - -#define PRCMU_ENABLE_PLLDSI 0x00000001 -#define PRCMU_DISABLE_PLLDSI 0x00000000 - -#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 - -/* - * mb0_transfer - state needed for mailbox 0 communication. - * @lock: The transaction lock. - */ -static struct { - spinlock_t lock; -} mb0_transfer; - -/* - * mb5_transfer - state needed for mailbox 5 communication. - * @lock: The transaction lock. - * @work: The transaction completion structure. - * @ack: Reply ("acknowledge") data. - */ -static struct { - struct mutex lock; - struct completion work; - struct { - u8 header; - u8 status; - u8 value[4]; - } ack; -} mb5_transfer; - -/* PRCMU TCDM base IO address. */ -static __iomem void *tcdm_base; - -/** - * db5500_prcmu_abb_read() - Read register value(s) from the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The read out value(s). - * @size: The number of registers to read. - * - * Reads register value(s) from the ABB. - * @size has to be <= 4. - */ -int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) -{ - int r; - - if ((size < 1) || (4 < size)) - return -EINVAL; - - mutex_lock(&mb5_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); - writeb(reg, PRCM_REQ_MB5_I2C_REG); - writeb(size, PRCM_REQ_MB5_I2C_SIZE); - writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb5_transfer.work); - - r = 0; - if ((mb5_transfer.ack.header == MB5H_I2C_READ) && - (mb5_transfer.ack.status == RC_SUCCESS)) - memcpy(value, mb5_transfer.ack.value, (size_t)size); - else - r = -EIO; - - mutex_unlock(&mb5_transfer.lock); - - return r; -} - -/** - * db5500_prcmu_abb_write() - Write register value(s) to the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The value(s) to write. - * @size: The number of registers to write. - * - * Writes register value(s) to the ABB. - * @size has to be <= 4. - */ -int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) -{ - int r; - - if ((size < 1) || (4 < size)) - return -EINVAL; - - mutex_lock(&mb5_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); - writeb(reg, PRCM_REQ_MB5_I2C_REG); - writeb(size, PRCM_REQ_MB5_I2C_SIZE); - memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size); - writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb5_transfer.work); - - if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) && - (mb5_transfer.ack.status == RC_SUCCESS)) - r = 0; - else - r = -EIO; - - mutex_unlock(&mb5_transfer.lock); - - return r; -} - -int db5500_prcmu_enable_dsipll(void) -{ - int i; - - /* Enable DSIPLL_RESETN resets */ - writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); - /* Unclamp DSIPLL in/out */ - writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); - /* Set DSI PLL FREQ */ - writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); - writel(PRCMU_DSI_PLLOUT_SEL_SETTING, - PRCM_DSI_PLLOUT_SEL); - /* Enable Escape clocks */ - writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); - - /* Start DSI PLL */ - writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); - /* Reset DSI PLL */ - writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); - for (i = 0; i < 10; i++) { - if ((readl(PRCM_PLLDSI_LOCKP) & - PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED) - break; - udelay(100); - } - /* Release DSIPLL_RESETN */ - writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); - return 0; -} - -int db5500_prcmu_disable_dsipll(void) -{ - /* Disable dsi pll */ - writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); - /* Disable escapeclock */ - writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); - return 0; -} - -int db5500_prcmu_set_display_clocks(void) -{ - /* HDMI and TVCLK Should be handled somewhere else */ - /* PLLDIV=8, PLLSW=2, CLKEN=1 */ - writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); - /* PLLDIV=14, PLLSW=2, CLKEN=1 */ - writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); - return 0; -} - -static void ack_dbb_wakeup(void) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) - cpu_relax(); - - writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER); - writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); -} - -static inline void print_unknown_header_warning(u8 n, u8 header) -{ - pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", - header, n); -} - -static bool read_mailbox_0(void) -{ - bool r; - u8 header; - - header = readb(PRCM_ACK_MB0_HEADER); - switch (header) { - case AMB0H_WAKE_UP: - r = true; - break; - default: - print_unknown_header_warning(0, header); - r = false; - break; - } - writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); - return r; -} - -static bool read_mailbox_1(void) -{ - writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_2(void) -{ - writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_3(void) -{ - writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_4(void) -{ - writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_5(void) -{ - u8 header; - - header = readb(PRCM_ACK_MB5_HEADER); - switch (header) { - case MB5H_I2C_READ: - memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4); - case MB5H_I2C_WRITE: - mb5_transfer.ack.header = header; - mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE); - complete(&mb5_transfer.work); - break; - default: - print_unknown_header_warning(5, header); - break; - } - writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_6(void) -{ - writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_7(void) -{ - writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); - return false; -} - -static bool (* const read_mailbox[NUM_MB])(void) = { - read_mailbox_0, - read_mailbox_1, - read_mailbox_2, - read_mailbox_3, - read_mailbox_4, - read_mailbox_5, - read_mailbox_6, - read_mailbox_7 -}; - -static irqreturn_t prcmu_irq_handler(int irq, void *data) -{ - u32 bits; - u8 n; - irqreturn_t r; - - bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); - if (unlikely(!bits)) - return IRQ_NONE; - - r = IRQ_HANDLED; - for (n = 0; bits; n++) { - if (bits & MBOX_BIT(n)) { - bits -= MBOX_BIT(n); - if (read_mailbox[n]()) - r = IRQ_WAKE_THREAD; - } - } - return r; -} - -static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) -{ - ack_dbb_wakeup(); - return IRQ_HANDLED; -} - -void __init db5500_prcmu_early_init(void) -{ - tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE); - spin_lock_init(&mb0_transfer.lock); - mutex_init(&mb5_transfer.lock); - init_completion(&mb5_transfer.work); -} - -/** - * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic - * - */ -int __init db5500_prcmu_init(void) -{ - int r = 0; - - if (ux500_is_svp() || !cpu_is_u5500()) - return -ENODEV; - - /* Clean up the mailbox interrupts after pre-kernel code. */ - writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); - - r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, - prcmu_irq_thread_fn, 0, "prcmu", NULL); - if (r < 0) { - pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n"); - return -EBUSY; - } - return 0; -} - -arch_initcall(db5500_prcmu_init); diff --git a/ANDROID_3.4.5/drivers/mfd/db8500-prcmu.c b/ANDROID_3.4.5/drivers/mfd/db8500-prcmu.c deleted file mode 100644 index 5be32489..00000000 --- a/ANDROID_3.4.5/drivers/mfd/db8500-prcmu.c +++ /dev/null @@ -1,3013 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> - * Author: Sundar Iyer <sundar.iyer@stericsson.com> - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> - * - * U8500 PRCM Unit interface driver - * - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/completion.h> -#include <linux/irq.h> -#include <linux/jiffies.h> -#include <linux/bitops.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/uaccess.h> -#include <linux/mfd/core.h> -#include <linux/mfd/dbx500-prcmu.h> -#include <linux/regulator/db8500-prcmu.h> -#include <linux/regulator/machine.h> -#include <asm/hardware/gic.h> -#include <mach/hardware.h> -#include <mach/irqs.h> -#include <mach/db8500-regs.h> -#include <mach/id.h> -#include "dbx500-prcmu-regs.h" - -/* Offset for the firmware version within the TCPM */ -#define PRCMU_FW_VERSION_OFFSET 0xA4 - -/* Index of different voltages to be used when accessing AVSData */ -#define PRCM_AVS_BASE 0x2FC -#define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) -#define PRCM_AVS_VBB_MAX_OPP (PRCM_AVS_BASE + 0x1) -#define PRCM_AVS_VBB_100_OPP (PRCM_AVS_BASE + 0x2) -#define PRCM_AVS_VBB_50_OPP (PRCM_AVS_BASE + 0x3) -#define PRCM_AVS_VARM_MAX_OPP (PRCM_AVS_BASE + 0x4) -#define PRCM_AVS_VARM_100_OPP (PRCM_AVS_BASE + 0x5) -#define PRCM_AVS_VARM_50_OPP (PRCM_AVS_BASE + 0x6) -#define PRCM_AVS_VARM_RET (PRCM_AVS_BASE + 0x7) -#define PRCM_AVS_VAPE_100_OPP (PRCM_AVS_BASE + 0x8) -#define PRCM_AVS_VAPE_50_OPP (PRCM_AVS_BASE + 0x9) -#define PRCM_AVS_VMOD_100_OPP (PRCM_AVS_BASE + 0xA) -#define PRCM_AVS_VMOD_50_OPP (PRCM_AVS_BASE + 0xB) -#define PRCM_AVS_VSAFE (PRCM_AVS_BASE + 0xC) - -#define PRCM_AVS_VOLTAGE 0 -#define PRCM_AVS_VOLTAGE_MASK 0x3f -#define PRCM_AVS_ISSLOWSTARTUP 6 -#define PRCM_AVS_ISSLOWSTARTUP_MASK (1 << PRCM_AVS_ISSLOWSTARTUP) -#define PRCM_AVS_ISMODEENABLE 7 -#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) - -#define PRCM_BOOT_STATUS 0xFFF -#define PRCM_ROMCODE_A2P 0xFFE -#define PRCM_ROMCODE_P2A 0xFFD -#define PRCM_XP70_CUR_PWR_STATE 0xFFC /* 4 BYTES */ - -#define PRCM_SW_RST_REASON 0xFF8 /* 2 bytes */ - -#define _PRCM_MBOX_HEADER 0xFE8 /* 16 bytes */ -#define PRCM_MBOX_HEADER_REQ_MB0 (_PRCM_MBOX_HEADER + 0x0) -#define PRCM_MBOX_HEADER_REQ_MB1 (_PRCM_MBOX_HEADER + 0x1) -#define PRCM_MBOX_HEADER_REQ_MB2 (_PRCM_MBOX_HEADER + 0x2) -#define PRCM_MBOX_HEADER_REQ_MB3 (_PRCM_MBOX_HEADER + 0x3) -#define PRCM_MBOX_HEADER_REQ_MB4 (_PRCM_MBOX_HEADER + 0x4) -#define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5) -#define PRCM_MBOX_HEADER_ACK_MB0 (_PRCM_MBOX_HEADER + 0x8) - -/* Req Mailboxes */ -#define PRCM_REQ_MB0 0xFDC /* 12 bytes */ -#define PRCM_REQ_MB1 0xFD0 /* 12 bytes */ -#define PRCM_REQ_MB2 0xFC0 /* 16 bytes */ -#define PRCM_REQ_MB3 0xE4C /* 372 bytes */ -#define PRCM_REQ_MB4 0xE48 /* 4 bytes */ -#define PRCM_REQ_MB5 0xE44 /* 4 bytes */ - -/* Ack Mailboxes */ -#define PRCM_ACK_MB0 0xE08 /* 52 bytes */ -#define PRCM_ACK_MB1 0xE04 /* 4 bytes */ -#define PRCM_ACK_MB2 0xE00 /* 4 bytes */ -#define PRCM_ACK_MB3 0xDFC /* 4 bytes */ -#define PRCM_ACK_MB4 0xDF8 /* 4 bytes */ -#define PRCM_ACK_MB5 0xDF4 /* 4 bytes */ - -/* Mailbox 0 headers */ -#define MB0H_POWER_STATE_TRANS 0 -#define MB0H_CONFIG_WAKEUPS_EXE 1 -#define MB0H_READ_WAKEUP_ACK 3 -#define MB0H_CONFIG_WAKEUPS_SLEEP 4 - -#define MB0H_WAKEUP_EXE 2 -#define MB0H_WAKEUP_SLEEP 5 - -/* Mailbox 0 REQs */ -#define PRCM_REQ_MB0_AP_POWER_STATE (PRCM_REQ_MB0 + 0x0) -#define PRCM_REQ_MB0_AP_PLL_STATE (PRCM_REQ_MB0 + 0x1) -#define PRCM_REQ_MB0_ULP_CLOCK_STATE (PRCM_REQ_MB0 + 0x2) -#define PRCM_REQ_MB0_DO_NOT_WFI (PRCM_REQ_MB0 + 0x3) -#define PRCM_REQ_MB0_WAKEUP_8500 (PRCM_REQ_MB0 + 0x4) -#define PRCM_REQ_MB0_WAKEUP_4500 (PRCM_REQ_MB0 + 0x8) - -/* Mailbox 0 ACKs */ -#define PRCM_ACK_MB0_AP_PWRSTTR_STATUS (PRCM_ACK_MB0 + 0x0) -#define PRCM_ACK_MB0_READ_POINTER (PRCM_ACK_MB0 + 0x1) -#define PRCM_ACK_MB0_WAKEUP_0_8500 (PRCM_ACK_MB0 + 0x4) -#define PRCM_ACK_MB0_WAKEUP_0_4500 (PRCM_ACK_MB0 + 0x8) -#define PRCM_ACK_MB0_WAKEUP_1_8500 (PRCM_ACK_MB0 + 0x1C) -#define PRCM_ACK_MB0_WAKEUP_1_4500 (PRCM_ACK_MB0 + 0x20) -#define PRCM_ACK_MB0_EVENT_4500_NUMBERS 20 - -/* Mailbox 1 headers */ -#define MB1H_ARM_APE_OPP 0x0 -#define MB1H_RESET_MODEM 0x2 -#define MB1H_REQUEST_APE_OPP_100_VOLT 0x3 -#define MB1H_RELEASE_APE_OPP_100_VOLT 0x4 -#define MB1H_RELEASE_USB_WAKEUP 0x5 -#define MB1H_PLL_ON_OFF 0x6 - -/* Mailbox 1 Requests */ -#define PRCM_REQ_MB1_ARM_OPP (PRCM_REQ_MB1 + 0x0) -#define PRCM_REQ_MB1_APE_OPP (PRCM_REQ_MB1 + 0x1) -#define PRCM_REQ_MB1_PLL_ON_OFF (PRCM_REQ_MB1 + 0x4) -#define PLL_SOC0_OFF 0x1 -#define PLL_SOC0_ON 0x2 -#define PLL_SOC1_OFF 0x4 -#define PLL_SOC1_ON 0x8 - -/* Mailbox 1 ACKs */ -#define PRCM_ACK_MB1_CURRENT_ARM_OPP (PRCM_ACK_MB1 + 0x0) -#define PRCM_ACK_MB1_CURRENT_APE_OPP (PRCM_ACK_MB1 + 0x1) -#define PRCM_ACK_MB1_APE_VOLTAGE_STATUS (PRCM_ACK_MB1 + 0x2) -#define PRCM_ACK_MB1_DVFS_STATUS (PRCM_ACK_MB1 + 0x3) - -/* Mailbox 2 headers */ -#define MB2H_DPS 0x0 -#define MB2H_AUTO_PWR 0x1 - -/* Mailbox 2 REQs */ -#define PRCM_REQ_MB2_SVA_MMDSP (PRCM_REQ_MB2 + 0x0) -#define PRCM_REQ_MB2_SVA_PIPE (PRCM_REQ_MB2 + 0x1) -#define PRCM_REQ_MB2_SIA_MMDSP (PRCM_REQ_MB2 + 0x2) -#define PRCM_REQ_MB2_SIA_PIPE (PRCM_REQ_MB2 + 0x3) -#define PRCM_REQ_MB2_SGA (PRCM_REQ_MB2 + 0x4) -#define PRCM_REQ_MB2_B2R2_MCDE (PRCM_REQ_MB2 + 0x5) -#define PRCM_REQ_MB2_ESRAM12 (PRCM_REQ_MB2 + 0x6) -#define PRCM_REQ_MB2_ESRAM34 (PRCM_REQ_MB2 + 0x7) -#define PRCM_REQ_MB2_AUTO_PM_SLEEP (PRCM_REQ_MB2 + 0x8) -#define PRCM_REQ_MB2_AUTO_PM_IDLE (PRCM_REQ_MB2 + 0xC) - -/* Mailbox 2 ACKs */ -#define PRCM_ACK_MB2_DPS_STATUS (PRCM_ACK_MB2 + 0x0) -#define HWACC_PWR_ST_OK 0xFE - -/* Mailbox 3 headers */ -#define MB3H_ANC 0x0 -#define MB3H_SIDETONE 0x1 -#define MB3H_SYSCLK 0xE - -/* Mailbox 3 Requests */ -#define PRCM_REQ_MB3_ANC_FIR_COEFF (PRCM_REQ_MB3 + 0x0) -#define PRCM_REQ_MB3_ANC_IIR_COEFF (PRCM_REQ_MB3 + 0x20) -#define PRCM_REQ_MB3_ANC_SHIFTER (PRCM_REQ_MB3 + 0x60) -#define PRCM_REQ_MB3_ANC_WARP (PRCM_REQ_MB3 + 0x64) -#define PRCM_REQ_MB3_SIDETONE_FIR_GAIN (PRCM_REQ_MB3 + 0x68) -#define PRCM_REQ_MB3_SIDETONE_FIR_COEFF (PRCM_REQ_MB3 + 0x6C) -#define PRCM_REQ_MB3_SYSCLK_MGT (PRCM_REQ_MB3 + 0x16C) - -/* Mailbox 4 headers */ -#define MB4H_DDR_INIT 0x0 -#define MB4H_MEM_ST 0x1 -#define MB4H_HOTDOG 0x12 -#define MB4H_HOTMON 0x13 -#define MB4H_HOT_PERIOD 0x14 -#define MB4H_A9WDOG_CONF 0x16 -#define MB4H_A9WDOG_EN 0x17 -#define MB4H_A9WDOG_DIS 0x18 -#define MB4H_A9WDOG_LOAD 0x19 -#define MB4H_A9WDOG_KICK 0x20 - -/* Mailbox 4 Requests */ -#define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0) -#define PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE (PRCM_REQ_MB4 + 0x1) -#define PRCM_REQ_MB4_ESRAM0_ST (PRCM_REQ_MB4 + 0x3) -#define PRCM_REQ_MB4_HOTDOG_THRESHOLD (PRCM_REQ_MB4 + 0x0) -#define PRCM_REQ_MB4_HOTMON_LOW (PRCM_REQ_MB4 + 0x0) -#define PRCM_REQ_MB4_HOTMON_HIGH (PRCM_REQ_MB4 + 0x1) -#define PRCM_REQ_MB4_HOTMON_CONFIG (PRCM_REQ_MB4 + 0x2) -#define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0) -#define HOTMON_CONFIG_LOW BIT(0) -#define HOTMON_CONFIG_HIGH BIT(1) -#define PRCM_REQ_MB4_A9WDOG_0 (PRCM_REQ_MB4 + 0x0) -#define PRCM_REQ_MB4_A9WDOG_1 (PRCM_REQ_MB4 + 0x1) -#define PRCM_REQ_MB4_A9WDOG_2 (PRCM_REQ_MB4 + 0x2) -#define PRCM_REQ_MB4_A9WDOG_3 (PRCM_REQ_MB4 + 0x3) -#define A9WDOG_AUTO_OFF_EN BIT(7) -#define A9WDOG_AUTO_OFF_DIS 0 -#define A9WDOG_ID_MASK 0xf - -/* Mailbox 5 Requests */ -#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) -#define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1) -#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2) -#define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3) -#define PRCMU_I2C_WRITE(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) -#define PRCMU_I2C_READ(slave) \ - (((slave) << 1) | BIT(0) | (cpu_is_u8500v2() ? BIT(6) : 0)) -#define PRCMU_I2C_STOP_EN BIT(3) - -/* Mailbox 5 ACKs */ -#define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1) -#define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3) -#define I2C_WR_OK 0x1 -#define I2C_RD_OK 0x2 - -#define NUM_MB 8 -#define MBOX_BIT BIT -#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) - -/* - * Wakeups/IRQs - */ - -#define WAKEUP_BIT_RTC BIT(0) -#define WAKEUP_BIT_RTT0 BIT(1) -#define WAKEUP_BIT_RTT1 BIT(2) -#define WAKEUP_BIT_HSI0 BIT(3) -#define WAKEUP_BIT_HSI1 BIT(4) -#define WAKEUP_BIT_CA_WAKE BIT(5) -#define WAKEUP_BIT_USB BIT(6) -#define WAKEUP_BIT_ABB BIT(7) -#define WAKEUP_BIT_ABB_FIFO BIT(8) -#define WAKEUP_BIT_SYSCLK_OK BIT(9) -#define WAKEUP_BIT_CA_SLEEP BIT(10) -#define WAKEUP_BIT_AC_WAKE_ACK BIT(11) -#define WAKEUP_BIT_SIDE_TONE_OK BIT(12) -#define WAKEUP_BIT_ANC_OK BIT(13) -#define WAKEUP_BIT_SW_ERROR BIT(14) -#define WAKEUP_BIT_AC_SLEEP_ACK BIT(15) -#define WAKEUP_BIT_ARM BIT(17) -#define WAKEUP_BIT_HOTMON_LOW BIT(18) -#define WAKEUP_BIT_HOTMON_HIGH BIT(19) -#define WAKEUP_BIT_MODEM_SW_RESET_REQ BIT(20) -#define WAKEUP_BIT_GPIO0 BIT(23) -#define WAKEUP_BIT_GPIO1 BIT(24) -#define WAKEUP_BIT_GPIO2 BIT(25) -#define WAKEUP_BIT_GPIO3 BIT(26) -#define WAKEUP_BIT_GPIO4 BIT(27) -#define WAKEUP_BIT_GPIO5 BIT(28) -#define WAKEUP_BIT_GPIO6 BIT(29) -#define WAKEUP_BIT_GPIO7 BIT(30) -#define WAKEUP_BIT_GPIO8 BIT(31) - -static struct { - bool valid; - struct prcmu_fw_version version; -} fw_info; - -/* - * This vector maps irq numbers to the bits in the bit field used in - * communication with the PRCMU firmware. - * - * The reason for having this is to keep the irq numbers contiguous even though - * the bits in the bit field are not. (The bits also have a tendency to move - * around, to further complicate matters.) - */ -#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE) -#define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name) -static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = { - IRQ_ENTRY(RTC), - IRQ_ENTRY(RTT0), - IRQ_ENTRY(RTT1), - IRQ_ENTRY(HSI0), - IRQ_ENTRY(HSI1), - IRQ_ENTRY(CA_WAKE), - IRQ_ENTRY(USB), - IRQ_ENTRY(ABB), - IRQ_ENTRY(ABB_FIFO), - IRQ_ENTRY(CA_SLEEP), - IRQ_ENTRY(ARM), - IRQ_ENTRY(HOTMON_LOW), - IRQ_ENTRY(HOTMON_HIGH), - IRQ_ENTRY(MODEM_SW_RESET_REQ), - IRQ_ENTRY(GPIO0), - IRQ_ENTRY(GPIO1), - IRQ_ENTRY(GPIO2), - IRQ_ENTRY(GPIO3), - IRQ_ENTRY(GPIO4), - IRQ_ENTRY(GPIO5), - IRQ_ENTRY(GPIO6), - IRQ_ENTRY(GPIO7), - IRQ_ENTRY(GPIO8) -}; - -#define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1) -#define WAKEUP_ENTRY(_name)[PRCMU_WAKEUP_INDEX_##_name] = (WAKEUP_BIT_##_name) -static u32 prcmu_wakeup_bit[NUM_PRCMU_WAKEUP_INDICES] = { - WAKEUP_ENTRY(RTC), - WAKEUP_ENTRY(RTT0), - WAKEUP_ENTRY(RTT1), - WAKEUP_ENTRY(HSI0), - WAKEUP_ENTRY(HSI1), - WAKEUP_ENTRY(USB), - WAKEUP_ENTRY(ABB), - WAKEUP_ENTRY(ABB_FIFO), - WAKEUP_ENTRY(ARM) -}; - -/* - * mb0_transfer - state needed for mailbox 0 communication. - * @lock: The transaction lock. - * @dbb_events_lock: A lock used to handle concurrent access to (parts of) - * the request data. - * @mask_work: Work structure used for (un)masking wakeup interrupts. - * @req: Request data that need to persist between requests. - */ -static struct { - spinlock_t lock; - spinlock_t dbb_irqs_lock; - struct work_struct mask_work; - struct mutex ac_wake_lock; - struct completion ac_wake_work; - struct { - u32 dbb_irqs; - u32 dbb_wakeups; - u32 abb_events; - } req; -} mb0_transfer; - -/* - * mb1_transfer - state needed for mailbox 1 communication. - * @lock: The transaction lock. - * @work: The transaction completion structure. - * @ape_opp: The current APE OPP. - * @ack: Reply ("acknowledge") data. - */ -static struct { - struct mutex lock; - struct completion work; - u8 ape_opp; - struct { - u8 header; - u8 arm_opp; - u8 ape_opp; - u8 ape_voltage_status; - } ack; -} mb1_transfer; - -/* - * mb2_transfer - state needed for mailbox 2 communication. - * @lock: The transaction lock. - * @work: The transaction completion structure. - * @auto_pm_lock: The autonomous power management configuration lock. - * @auto_pm_enabled: A flag indicating whether autonomous PM is enabled. - * @req: Request data that need to persist between requests. - * @ack: Reply ("acknowledge") data. - */ -static struct { - struct mutex lock; - struct completion work; - spinlock_t auto_pm_lock; - bool auto_pm_enabled; - struct { - u8 status; - } ack; -} mb2_transfer; - -/* - * mb3_transfer - state needed for mailbox 3 communication. - * @lock: The request lock. - * @sysclk_lock: A lock used to handle concurrent sysclk requests. - * @sysclk_work: Work structure used for sysclk requests. - */ -static struct { - spinlock_t lock; - struct mutex sysclk_lock; - struct completion sysclk_work; -} mb3_transfer; - -/* - * mb4_transfer - state needed for mailbox 4 communication. - * @lock: The transaction lock. - * @work: The transaction completion structure. - */ -static struct { - struct mutex lock; - struct completion work; -} mb4_transfer; - -/* - * mb5_transfer - state needed for mailbox 5 communication. - * @lock: The transaction lock. - * @work: The transaction completion structure. - * @ack: Reply ("acknowledge") data. - */ -static struct { - struct mutex lock; - struct completion work; - struct { - u8 status; - u8 value; - } ack; -} mb5_transfer; - -static atomic_t ac_wake_req_state = ATOMIC_INIT(0); - -/* Spinlocks */ -static DEFINE_SPINLOCK(prcmu_lock); -static DEFINE_SPINLOCK(clkout_lock); - -/* Global var to runtime determine TCDM base for v2 or v1 */ -static __iomem void *tcdm_base; - -struct clk_mgt { - void __iomem *reg; - u32 pllsw; - int branch; - bool clk38div; -}; - -enum { - PLL_RAW, - PLL_FIX, - PLL_DIV -}; - -static DEFINE_SPINLOCK(clk_mgt_lock); - -#define CLK_MGT_ENTRY(_name, _branch, _clk38div)[PRCMU_##_name] = \ - { (PRCM_##_name##_MGT), 0 , _branch, _clk38div} -struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { - CLK_MGT_ENTRY(SGACLK, PLL_DIV, false), - CLK_MGT_ENTRY(UARTCLK, PLL_FIX, true), - CLK_MGT_ENTRY(MSP02CLK, PLL_FIX, true), - CLK_MGT_ENTRY(MSP1CLK, PLL_FIX, true), - CLK_MGT_ENTRY(I2CCLK, PLL_FIX, true), - CLK_MGT_ENTRY(SDMMCCLK, PLL_DIV, true), - CLK_MGT_ENTRY(SLIMCLK, PLL_FIX, true), - CLK_MGT_ENTRY(PER1CLK, PLL_DIV, true), - CLK_MGT_ENTRY(PER2CLK, PLL_DIV, true), - CLK_MGT_ENTRY(PER3CLK, PLL_DIV, true), - CLK_MGT_ENTRY(PER5CLK, PLL_DIV, true), - CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true), - CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true), - CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true), - CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true), - CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true), - CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true), - CLK_MGT_ENTRY(HDMICLK, PLL_FIX, false), - CLK_MGT_ENTRY(APEATCLK, PLL_DIV, true), - CLK_MGT_ENTRY(APETRACECLK, PLL_DIV, true), - CLK_MGT_ENTRY(MCDECLK, PLL_DIV, true), - CLK_MGT_ENTRY(IPI2CCLK, PLL_FIX, true), - CLK_MGT_ENTRY(DSIALTCLK, PLL_FIX, false), - CLK_MGT_ENTRY(DMACLK, PLL_DIV, true), - CLK_MGT_ENTRY(B2R2CLK, PLL_DIV, true), - CLK_MGT_ENTRY(TVCLK, PLL_FIX, true), - CLK_MGT_ENTRY(SSPCLK, PLL_FIX, true), - CLK_MGT_ENTRY(RNGCLK, PLL_FIX, true), - CLK_MGT_ENTRY(UICCCLK, PLL_FIX, false), -}; - -struct dsiclk { - u32 divsel_mask; - u32 divsel_shift; - u32 divsel; -}; - -static struct dsiclk dsiclk[2] = { - { - .divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK, - .divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT, - .divsel = PRCM_DSI_PLLOUT_SEL_PHI, - }, - { - .divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK, - .divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT, - .divsel = PRCM_DSI_PLLOUT_SEL_PHI, - } -}; - -struct dsiescclk { - u32 en; - u32 div_mask; - u32 div_shift; -}; - -static struct dsiescclk dsiescclk[3] = { - { - .en = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN, - .div_mask = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK, - .div_shift = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT, - }, - { - .en = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN, - .div_mask = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK, - .div_shift = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT, - }, - { - .en = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN, - .div_mask = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK, - .div_shift = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT, - } -}; - -/* -* Used by MCDE to setup all necessary PRCMU registers -*/ -#define PRCMU_RESET_DSIPLL 0x00004000 -#define PRCMU_UNCLAMP_DSIPLL 0x00400800 - -#define PRCMU_CLK_PLL_DIV_SHIFT 0 -#define PRCMU_CLK_PLL_SW_SHIFT 5 -#define PRCMU_CLK_38 (1 << 9) -#define PRCMU_CLK_38_SRC (1 << 10) -#define PRCMU_CLK_38_DIV (1 << 11) - -/* PLLDIV=12, PLLSW=4 (PLLDDR) */ -#define PRCMU_DSI_CLOCK_SETTING 0x0000008C - -/* DPI 50000000 Hz */ -#define PRCMU_DPI_CLOCK_SETTING ((1 << PRCMU_CLK_PLL_SW_SHIFT) | \ - (16 << PRCMU_CLK_PLL_DIV_SHIFT)) -#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000E00 - -/* D=101, N=1, R=4, SELDIV2=0 */ -#define PRCMU_PLLDSI_FREQ_SETTING 0x00040165 - -#define PRCMU_ENABLE_PLLDSI 0x00000001 -#define PRCMU_DISABLE_PLLDSI 0x00000000 -#define PRCMU_RELEASE_RESET_DSS 0x0000400C -#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000202 -/* ESC clk, div0=1, div1=1, div2=3 */ -#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x07030101 -#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00030101 -#define PRCMU_DSI_RESET_SW 0x00000007 - -#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 - -int db8500_prcmu_enable_dsipll(void) -{ - int i; - - /* Clear DSIPLL_RESETN */ - writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); - /* Unclamp DSIPLL in/out */ - writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); - - /* Set DSI PLL FREQ */ - writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); - writel(PRCMU_DSI_PLLOUT_SEL_SETTING, PRCM_DSI_PLLOUT_SEL); - /* Enable Escape clocks */ - writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); - - /* Start DSI PLL */ - writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); - /* Reset DSI PLL */ - writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); - for (i = 0; i < 10; i++) { - if ((readl(PRCM_PLLDSI_LOCKP) & PRCMU_PLLDSI_LOCKP_LOCKED) - == PRCMU_PLLDSI_LOCKP_LOCKED) - break; - udelay(100); - } - /* Set DSIPLL_RESETN */ - writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); - return 0; -} - -int db8500_prcmu_disable_dsipll(void) -{ - /* Disable dsi pll */ - writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); - /* Disable escapeclock */ - writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); - return 0; -} - -int db8500_prcmu_set_display_clocks(void) -{ - unsigned long flags; - - spin_lock_irqsave(&clk_mgt_lock, flags); - - /* Grab the HW semaphore. */ - while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) - cpu_relax(); - - writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); - writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); - writel(PRCMU_DPI_CLOCK_SETTING, PRCM_LCDCLK_MGT); - - /* Release the HW semaphore. */ - writel(0, PRCM_SEM); - - spin_unlock_irqrestore(&clk_mgt_lock, flags); - - return 0; -} - -u32 db8500_prcmu_read(unsigned int reg) -{ - return readl(_PRCMU_BASE + reg); -} - -void db8500_prcmu_write(unsigned int reg, u32 value) -{ - unsigned long flags; - - spin_lock_irqsave(&prcmu_lock, flags); - writel(value, (_PRCMU_BASE + reg)); - spin_unlock_irqrestore(&prcmu_lock, flags); -} - -void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value) -{ - u32 val; - unsigned long flags; - - spin_lock_irqsave(&prcmu_lock, flags); - val = readl(_PRCMU_BASE + reg); - val = ((val & ~mask) | (value & mask)); - writel(val, (_PRCMU_BASE + reg)); - spin_unlock_irqrestore(&prcmu_lock, flags); -} - -struct prcmu_fw_version *prcmu_get_fw_version(void) -{ - return fw_info.valid ? &fw_info.version : NULL; -} - -bool prcmu_has_arm_maxopp(void) -{ - return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) & - PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK; -} - -/** - * prcmu_get_boot_status - PRCMU boot status checking - * Returns: the current PRCMU boot status - */ -int prcmu_get_boot_status(void) -{ - return readb(tcdm_base + PRCM_BOOT_STATUS); -} - -/** - * prcmu_set_rc_a2p - This function is used to run few power state sequences - * @val: Value to be set, i.e. transition requested - * Returns: 0 on success, -EINVAL on invalid argument - * - * This function is used to run the following power state sequences - - * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep - */ -int prcmu_set_rc_a2p(enum romcode_write val) -{ - if (val < RDY_2_DS || val > RDY_2_XP70_RST) - return -EINVAL; - writeb(val, (tcdm_base + PRCM_ROMCODE_A2P)); - return 0; -} - -/** - * prcmu_get_rc_p2a - This function is used to get power state sequences - * Returns: the power transition that has last happened - * - * This function can return the following transitions- - * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep - */ -enum romcode_read prcmu_get_rc_p2a(void) -{ - return readb(tcdm_base + PRCM_ROMCODE_P2A); -} - -/** - * prcmu_get_current_mode - Return the current XP70 power mode - * Returns: Returns the current AP(ARM) power mode: init, - * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset - */ -enum ap_pwrst prcmu_get_xp70_current_state(void) -{ - return readb(tcdm_base + PRCM_XP70_CUR_PWR_STATE); -} - -/** - * prcmu_config_clkout - Configure one of the programmable clock outputs. - * @clkout: The CLKOUT number (0 or 1). - * @source: The clock to be used (one of the PRCMU_CLKSRC_*). - * @div: The divider to be applied. - * - * Configures one of the programmable clock outputs (CLKOUTs). - * @div should be in the range [1,63] to request a configuration, or 0 to - * inform that the configuration is no longer requested. - */ -int prcmu_config_clkout(u8 clkout, u8 source, u8 div) -{ - static int requests[2]; - int r = 0; - unsigned long flags; - u32 val; - u32 bits; - u32 mask; - u32 div_mask; - - BUG_ON(clkout > 1); - BUG_ON(div > 63); - BUG_ON((clkout == 0) && (source > PRCMU_CLKSRC_CLK009)); - - if (!div && !requests[clkout]) - return -EINVAL; - - switch (clkout) { - case 0: - div_mask = PRCM_CLKOCR_CLKODIV0_MASK; - mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK); - bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) | - (div << PRCM_CLKOCR_CLKODIV0_SHIFT)); - break; - case 1: - div_mask = PRCM_CLKOCR_CLKODIV1_MASK; - mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK | - PRCM_CLKOCR_CLK1TYPE); - bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) | - (div << PRCM_CLKOCR_CLKODIV1_SHIFT)); - break; - } - bits &= mask; - - spin_lock_irqsave(&clkout_lock, flags); - - val = readl(PRCM_CLKOCR); - if (val & div_mask) { - if (div) { - if ((val & mask) != bits) { - r = -EBUSY; - goto unlock_and_return; - } - } else { - if ((val & mask & ~div_mask) != bits) { - r = -EINVAL; - goto unlock_and_return; - } - } - } - writel((bits | (val & ~mask)), PRCM_CLKOCR); - requests[clkout] += (div ? 1 : -1); - -unlock_and_return: - spin_unlock_irqrestore(&clkout_lock, flags); - - return r; -} - -int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) -{ - unsigned long flags; - - BUG_ON((state < PRCMU_AP_SLEEP) || (PRCMU_AP_DEEP_IDLE < state)); - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) - cpu_relax(); - - writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); - writeb(state, (tcdm_base + PRCM_REQ_MB0_AP_POWER_STATE)); - writeb((keep_ap_pll ? 1 : 0), (tcdm_base + PRCM_REQ_MB0_AP_PLL_STATE)); - writeb((keep_ulp_clk ? 1 : 0), - (tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE)); - writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI)); - writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); - - return 0; -} - -u8 db8500_prcmu_get_power_state_result(void) -{ - return readb(tcdm_base + PRCM_ACK_MB0_AP_PWRSTTR_STATUS); -} - -/* This function decouple the gic from the prcmu */ -int db8500_prcmu_gic_decouple(void) -{ - u32 val = readl(PRCM_A9_MASK_REQ); - - /* Set bit 0 register value to 1 */ - writel(val | PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ, - PRCM_A9_MASK_REQ); - - /* Make sure the register is updated */ - readl(PRCM_A9_MASK_REQ); - - /* Wait a few cycles for the gic mask completion */ - udelay(1); - - return 0; -} - -/* This function recouple the gic with the prcmu */ -int db8500_prcmu_gic_recouple(void) -{ - u32 val = readl(PRCM_A9_MASK_REQ); - - /* Set bit 0 register value to 0 */ - writel(val & ~PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ, PRCM_A9_MASK_REQ); - - return 0; -} - -#define PRCMU_GIC_NUMBER_REGS 5 - -/* - * This function checks if there are pending irq on the gic. It only - * makes sense if the gic has been decoupled before with the - * db8500_prcmu_gic_decouple function. Disabling an interrupt only - * disables the forwarding of the interrupt to any CPU interface. It - * does not prevent the interrupt from changing state, for example - * becoming pending, or active and pending if it is already - * active. Hence, we have to check the interrupt is pending *and* is - * active. - */ -bool db8500_prcmu_gic_pending_irq(void) -{ - u32 pr; /* Pending register */ - u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); - int i; - - /* 5 registers. STI & PPI not skipped */ - for (i = 0; i < PRCMU_GIC_NUMBER_REGS; i++) { - - pr = readl_relaxed(dist_base + GIC_DIST_PENDING_SET + i * 4); - er = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); - - if (pr & er) - return true; /* There is a pending interrupt */ - } - - return false; -} - -/* - * This function checks if there are pending interrupt on the - * prcmu which has been delegated to monitor the irqs with the - * db8500_prcmu_copy_gic_settings function. - */ -bool db8500_prcmu_pending_irq(void) -{ - u32 it, im; - int i; - - for (i = 0; i < PRCMU_GIC_NUMBER_REGS - 1; i++) { - it = readl(PRCM_ARMITVAL31TO0 + i * 4); - im = readl(PRCM_ARMITMSK31TO0 + i * 4); - if (it & im) - return true; /* There is a pending interrupt */ - } - - return false; -} - -/* - * This function checks if the specified cpu is in in WFI. It's usage - * makes sense only if the gic is decoupled with the db8500_prcmu_gic_decouple - * function. Of course passing smp_processor_id() to this function will - * always return false... - */ -bool db8500_prcmu_is_cpu_in_wfi(int cpu) -{ - return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : - PRCM_ARM_WFI_STANDBY_WFI0; -} - -/* - * This function copies the gic SPI settings to the prcmu in order to - * monitor them and abort/finish the retention/off sequence or state. - */ -int db8500_prcmu_copy_gic_settings(void) -{ - u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); - int i; - - /* We skip the STI and PPI */ - for (i = 0; i < PRCMU_GIC_NUMBER_REGS - 1; i++) { - er = readl_relaxed(dist_base + - GIC_DIST_ENABLE_SET + (i + 1) * 4); - writel(er, PRCM_ARMITMSK31TO0 + i * 4); - } - - return 0; -} - -/* This function should only be called while mb0_transfer.lock is held. */ -static void config_wakeups(void) -{ - const u8 header[2] = { - MB0H_CONFIG_WAKEUPS_EXE, - MB0H_CONFIG_WAKEUPS_SLEEP - }; - static u32 last_dbb_events; - static u32 last_abb_events; - u32 dbb_events; - u32 abb_events; - unsigned int i; - - dbb_events = mb0_transfer.req.dbb_irqs | mb0_transfer.req.dbb_wakeups; - dbb_events |= (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK); - - abb_events = mb0_transfer.req.abb_events; - - if ((dbb_events == last_dbb_events) && (abb_events == last_abb_events)) - return; - - for (i = 0; i < 2; i++) { - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) - cpu_relax(); - writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500)); - writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500)); - writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); - writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); - } - last_dbb_events = dbb_events; - last_abb_events = abb_events; -} - -void db8500_prcmu_enable_wakeups(u32 wakeups) -{ - unsigned long flags; - u32 bits; - int i; - - BUG_ON(wakeups != (wakeups & VALID_WAKEUPS)); - - for (i = 0, bits = 0; i < NUM_PRCMU_WAKEUP_INDICES; i++) { - if (wakeups & BIT(i)) - bits |= prcmu_wakeup_bit[i]; - } - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - mb0_transfer.req.dbb_wakeups = bits; - config_wakeups(); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); -} - -void db8500_prcmu_config_abb_event_readout(u32 abb_events) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - mb0_transfer.req.abb_events = abb_events; - config_wakeups(); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); -} - -void db8500_prcmu_get_abb_event_buffer(void __iomem **buf) -{ - if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) - *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500); - else - *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_0_4500); -} - -/** - * db8500_prcmu_set_arm_opp - set the appropriate ARM OPP - * @opp: The new ARM operating point to which transition is to be made - * Returns: 0 on success, non-zero on failure - * - * This function sets the the operating point of the ARM. - */ -int db8500_prcmu_set_arm_opp(u8 opp) -{ - int r; - - if (opp < ARM_NO_CHANGE || opp > ARM_EXTCLK) - return -EINVAL; - - r = 0; - - mutex_lock(&mb1_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); - writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); - - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || - (mb1_transfer.ack.arm_opp != opp)) - r = -EIO; - - mutex_unlock(&mb1_transfer.lock); - - return r; -} - -/** - * db8500_prcmu_get_arm_opp - get the current ARM OPP - * - * Returns: the current ARM OPP - */ -int db8500_prcmu_get_arm_opp(void) -{ - return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP); -} - -/** - * db8500_prcmu_get_ddr_opp - get the current DDR OPP - * - * Returns: the current DDR OPP - */ -int db8500_prcmu_get_ddr_opp(void) -{ - return readb(PRCM_DDR_SUBSYS_APE_MINBW); -} - -/** - * db8500_set_ddr_opp - set the appropriate DDR OPP - * @opp: The new DDR operating point to which transition is to be made - * Returns: 0 on success, non-zero on failure - * - * This function sets the operating point of the DDR. - */ -int db8500_prcmu_set_ddr_opp(u8 opp) -{ - if (opp < DDR_100_OPP || opp > DDR_25_OPP) - return -EINVAL; - /* Changing the DDR OPP can hang the hardware pre-v21 */ - if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) - writeb(opp, PRCM_DDR_SUBSYS_APE_MINBW); - - return 0; -} - -/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */ -static void request_even_slower_clocks(bool enable) -{ - void __iomem *clock_reg[] = { - PRCM_ACLK_MGT, - PRCM_DMACLK_MGT - }; - unsigned long flags; - unsigned int i; - - spin_lock_irqsave(&clk_mgt_lock, flags); - - /* Grab the HW semaphore. */ - while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) - cpu_relax(); - - for (i = 0; i < ARRAY_SIZE(clock_reg); i++) { - u32 val; - u32 div; - - val = readl(clock_reg[i]); - div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK); - if (enable) { - if ((div <= 1) || (div > 15)) { - pr_err("prcmu: Bad clock divider %d in %s\n", - div, __func__); - goto unlock_and_return; - } - div <<= 1; - } else { - if (div <= 2) - goto unlock_and_return; - div >>= 1; - } - val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) | - (div & PRCM_CLK_MGT_CLKPLLDIV_MASK)); - writel(val, clock_reg[i]); - } - -unlock_and_return: - /* Release the HW semaphore. */ - writel(0, PRCM_SEM); - - spin_unlock_irqrestore(&clk_mgt_lock, flags); -} - -/** - * db8500_set_ape_opp - set the appropriate APE OPP - * @opp: The new APE operating point to which transition is to be made - * Returns: 0 on success, non-zero on failure - * - * This function sets the operating point of the APE. - */ -int db8500_prcmu_set_ape_opp(u8 opp) -{ - int r = 0; - - if (opp == mb1_transfer.ape_opp) - return 0; - - mutex_lock(&mb1_transfer.lock); - - if (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP) - request_even_slower_clocks(false); - - if ((opp != APE_100_OPP) && (mb1_transfer.ape_opp != APE_100_OPP)) - goto skip_message; - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); - writeb(((opp == APE_50_PARTLY_25_OPP) ? APE_50_OPP : opp), - (tcdm_base + PRCM_REQ_MB1_APE_OPP)); - - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || - (mb1_transfer.ack.ape_opp != opp)) - r = -EIO; - -skip_message: - if ((!r && (opp == APE_50_PARTLY_25_OPP)) || - (r && (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP))) - request_even_slower_clocks(true); - if (!r) - mb1_transfer.ape_opp = opp; - - mutex_unlock(&mb1_transfer.lock); - - return r; -} - -/** - * db8500_prcmu_get_ape_opp - get the current APE OPP - * - * Returns: the current APE OPP - */ -int db8500_prcmu_get_ape_opp(void) -{ - return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP); -} - -/** - * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage - * @enable: true to request the higher voltage, false to drop a request. - * - * Calls to this function to enable and disable requests must be balanced. - */ -int prcmu_request_ape_opp_100_voltage(bool enable) -{ - int r = 0; - u8 header; - static unsigned int requests; - - mutex_lock(&mb1_transfer.lock); - - if (enable) { - if (0 != requests++) - goto unlock_and_return; - header = MB1H_REQUEST_APE_OPP_100_VOLT; - } else { - if (requests == 0) { - r = -EIO; - goto unlock_and_return; - } else if (1 != requests--) { - goto unlock_and_return; - } - header = MB1H_RELEASE_APE_OPP_100_VOLT; - } - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - if ((mb1_transfer.ack.header != header) || - ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) - r = -EIO; - -unlock_and_return: - mutex_unlock(&mb1_transfer.lock); - - return r; -} - -/** - * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup - * - * This function releases the power state requirements of a USB wakeup. - */ -int prcmu_release_usb_wakeup_state(void) -{ - int r = 0; - - mutex_lock(&mb1_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(MB1H_RELEASE_USB_WAKEUP, - (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) || - ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) - r = -EIO; - - mutex_unlock(&mb1_transfer.lock); - - return r; -} - -static int request_pll(u8 clock, bool enable) -{ - int r = 0; - - if (clock == PRCMU_PLLSOC0) - clock = (enable ? PLL_SOC0_ON : PLL_SOC0_OFF); - else if (clock == PRCMU_PLLSOC1) - clock = (enable ? PLL_SOC1_ON : PLL_SOC1_OFF); - else - return -EINVAL; - - mutex_lock(&mb1_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(MB1H_PLL_ON_OFF, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - writeb(clock, (tcdm_base + PRCM_REQ_MB1_PLL_ON_OFF)); - - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - if (mb1_transfer.ack.header != MB1H_PLL_ON_OFF) - r = -EIO; - - mutex_unlock(&mb1_transfer.lock); - - return r; -} - -/** - * db8500_prcmu_set_epod - set the state of a EPOD (power domain) - * @epod_id: The EPOD to set - * @epod_state: The new EPOD state - * - * This function sets the state of a EPOD (power domain). It may not be called - * from interrupt context. - */ -int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state) -{ - int r = 0; - bool ram_retention = false; - int i; - - /* check argument */ - BUG_ON(epod_id >= NUM_EPOD_ID); - - /* set flag if retention is possible */ - switch (epod_id) { - case EPOD_ID_SVAMMDSP: - case EPOD_ID_SIAMMDSP: - case EPOD_ID_ESRAM12: - case EPOD_ID_ESRAM34: - ram_retention = true; - break; - } - - /* check argument */ - BUG_ON(epod_state > EPOD_STATE_ON); - BUG_ON(epod_state == EPOD_STATE_RAMRET && !ram_retention); - - /* get lock */ - mutex_lock(&mb2_transfer.lock); - - /* wait for mailbox */ - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(2)) - cpu_relax(); - - /* fill in mailbox */ - for (i = 0; i < NUM_EPOD_ID; i++) - writeb(EPOD_STATE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB2 + i)); - writeb(epod_state, (tcdm_base + PRCM_REQ_MB2 + epod_id)); - - writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2)); - - writel(MBOX_BIT(2), PRCM_MBOX_CPU_SET); - - /* - * The current firmware version does not handle errors correctly, - * and we cannot recover if there is an error. - * This is expected to change when the firmware is updated. - */ - if (!wait_for_completion_timeout(&mb2_transfer.work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", - __func__); - r = -EIO; - goto unlock_and_return; - } - - if (mb2_transfer.ack.status != HWACC_PWR_ST_OK) - r = -EIO; - -unlock_and_return: - mutex_unlock(&mb2_transfer.lock); - return r; -} - -/** - * prcmu_configure_auto_pm - Configure autonomous power management. - * @sleep: Configuration for ApSleep. - * @idle: Configuration for ApIdle. - */ -void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, - struct prcmu_auto_pm_config *idle) -{ - u32 sleep_cfg; - u32 idle_cfg; - unsigned long flags; - - BUG_ON((sleep == NULL) || (idle == NULL)); - - sleep_cfg = (sleep->sva_auto_pm_enable & 0xF); - sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF)); - sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF)); - sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF)); - sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF)); - sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF)); - - idle_cfg = (idle->sva_auto_pm_enable & 0xF); - idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF)); - idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF)); - idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF)); - idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF)); - idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF)); - - spin_lock_irqsave(&mb2_transfer.auto_pm_lock, flags); - - /* - * The autonomous power management configuration is done through - * fields in mailbox 2, but these fields are only used as shared - * variables - i.e. there is no need to send a message. - */ - writel(sleep_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_SLEEP)); - writel(idle_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_IDLE)); - - mb2_transfer.auto_pm_enabled = - ((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || - (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) || - (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || - (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON)); - - spin_unlock_irqrestore(&mb2_transfer.auto_pm_lock, flags); -} -EXPORT_SYMBOL(prcmu_configure_auto_pm); - -bool prcmu_is_auto_pm_enabled(void) -{ - return mb2_transfer.auto_pm_enabled; -} - -static int request_sysclk(bool enable) -{ - int r; - unsigned long flags; - - r = 0; - - mutex_lock(&mb3_transfer.sysclk_lock); - - spin_lock_irqsave(&mb3_transfer.lock, flags); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(3)) - cpu_relax(); - - writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT)); - - writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3)); - writel(MBOX_BIT(3), PRCM_MBOX_CPU_SET); - - spin_unlock_irqrestore(&mb3_transfer.lock, flags); - - /* - * The firmware only sends an ACK if we want to enable the - * SysClk, and it succeeds. - */ - if (enable && !wait_for_completion_timeout(&mb3_transfer.sysclk_work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", - __func__); - r = -EIO; - } - - mutex_unlock(&mb3_transfer.sysclk_lock); - - return r; -} - -static int request_timclk(bool enable) -{ - u32 val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK); - - if (!enable) - val |= PRCM_TCR_STOP_TIMERS; - writel(val, PRCM_TCR); - - return 0; -} - -static int request_clock(u8 clock, bool enable) -{ - u32 val; - unsigned long flags; - - spin_lock_irqsave(&clk_mgt_lock, flags); - - /* Grab the HW semaphore. */ - while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) - cpu_relax(); - - val = readl(clk_mgt[clock].reg); - if (enable) { - val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw); - } else { - clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK); - val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK); - } - writel(val, clk_mgt[clock].reg); - - /* Release the HW semaphore. */ - writel(0, PRCM_SEM); - - spin_unlock_irqrestore(&clk_mgt_lock, flags); - - return 0; -} - -static int request_sga_clock(u8 clock, bool enable) -{ - u32 val; - int ret; - - if (enable) { - val = readl(PRCM_CGATING_BYPASS); - writel(val | PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS); - } - - ret = request_clock(clock, enable); - - if (!ret && !enable) { - val = readl(PRCM_CGATING_BYPASS); - writel(val & ~PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS); - } - - return ret; -} - -static inline bool plldsi_locked(void) -{ - return (readl(PRCM_PLLDSI_LOCKP) & - (PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 | - PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3)) == - (PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 | - PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3); -} - -static int request_plldsi(bool enable) -{ - int r = 0; - u32 val; - - writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP | - PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI), (enable ? - PRCM_MMIP_LS_CLAMP_CLR : PRCM_MMIP_LS_CLAMP_SET)); - - val = readl(PRCM_PLLDSI_ENABLE); - if (enable) - val |= PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE; - else - val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE; - writel(val, PRCM_PLLDSI_ENABLE); - - if (enable) { - unsigned int i; - bool locked = plldsi_locked(); - - for (i = 10; !locked && (i > 0); --i) { - udelay(100); - locked = plldsi_locked(); - } - if (locked) { - writel(PRCM_APE_RESETN_DSIPLL_RESETN, - PRCM_APE_RESETN_SET); - } else { - writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP | - PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI), - PRCM_MMIP_LS_CLAMP_SET); - val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE; - writel(val, PRCM_PLLDSI_ENABLE); - r = -EAGAIN; - } - } else { - writel(PRCM_APE_RESETN_DSIPLL_RESETN, PRCM_APE_RESETN_CLR); - } - return r; -} - -static int request_dsiclk(u8 n, bool enable) -{ - u32 val; - - val = readl(PRCM_DSI_PLLOUT_SEL); - val &= ~dsiclk[n].divsel_mask; - val |= ((enable ? dsiclk[n].divsel : PRCM_DSI_PLLOUT_SEL_OFF) << - dsiclk[n].divsel_shift); - writel(val, PRCM_DSI_PLLOUT_SEL); - return 0; -} - -static int request_dsiescclk(u8 n, bool enable) -{ - u32 val; - - val = readl(PRCM_DSITVCLK_DIV); - enable ? (val |= dsiescclk[n].en) : (val &= ~dsiescclk[n].en); - writel(val, PRCM_DSITVCLK_DIV); - return 0; -} - -/** - * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled. - * @clock: The clock for which the request is made. - * @enable: Whether the clock should be enabled (true) or disabled (false). - * - * This function should only be used by the clock implementation. - * Do not use it from any other place! - */ -int db8500_prcmu_request_clock(u8 clock, bool enable) -{ - if (clock == PRCMU_SGACLK) - return request_sga_clock(clock, enable); - else if (clock < PRCMU_NUM_REG_CLOCKS) - return request_clock(clock, enable); - else if (clock == PRCMU_TIMCLK) - return request_timclk(enable); - else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) - return request_dsiclk((clock - PRCMU_DSI0CLK), enable); - else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK)) - return request_dsiescclk((clock - PRCMU_DSI0ESCCLK), enable); - else if (clock == PRCMU_PLLDSI) - return request_plldsi(enable); - else if (clock == PRCMU_SYSCLK) - return request_sysclk(enable); - else if ((clock == PRCMU_PLLSOC0) || (clock == PRCMU_PLLSOC1)) - return request_pll(clock, enable); - else - return -EINVAL; -} - -static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate, - int branch) -{ - u64 rate; - u32 val; - u32 d; - u32 div = 1; - - val = readl(reg); - - rate = src_rate; - rate *= ((val & PRCM_PLL_FREQ_D_MASK) >> PRCM_PLL_FREQ_D_SHIFT); - - d = ((val & PRCM_PLL_FREQ_N_MASK) >> PRCM_PLL_FREQ_N_SHIFT); - if (d > 1) - div *= d; - - d = ((val & PRCM_PLL_FREQ_R_MASK) >> PRCM_PLL_FREQ_R_SHIFT); - if (d > 1) - div *= d; - - if (val & PRCM_PLL_FREQ_SELDIV2) - div *= 2; - - if ((branch == PLL_FIX) || ((branch == PLL_DIV) && - (val & PRCM_PLL_FREQ_DIV2EN) && - ((reg == PRCM_PLLSOC0_FREQ) || - (reg == PRCM_PLLDDR_FREQ)))) - div *= 2; - - (void)do_div(rate, div); - - return (unsigned long)rate; -} - -#define ROOT_CLOCK_RATE 38400000 - -static unsigned long clock_rate(u8 clock) -{ - u32 val; - u32 pllsw; - unsigned long rate = ROOT_CLOCK_RATE; - - val = readl(clk_mgt[clock].reg); - - if (val & PRCM_CLK_MGT_CLK38) { - if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV)) - rate /= 2; - return rate; - } - - val |= clk_mgt[clock].pllsw; - pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK); - - if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC0) - rate = pll_rate(PRCM_PLLSOC0_FREQ, rate, clk_mgt[clock].branch); - else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC1) - rate = pll_rate(PRCM_PLLSOC1_FREQ, rate, clk_mgt[clock].branch); - else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_DDR) - rate = pll_rate(PRCM_PLLDDR_FREQ, rate, clk_mgt[clock].branch); - else - return 0; - - if ((clock == PRCMU_SGACLK) && - (val & PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN)) { - u64 r = (rate * 10); - - (void)do_div(r, 25); - return (unsigned long)r; - } - val &= PRCM_CLK_MGT_CLKPLLDIV_MASK; - if (val) - return rate / val; - else - return 0; -} - -static unsigned long dsiclk_rate(u8 n) -{ - u32 divsel; - u32 div = 1; - - divsel = readl(PRCM_DSI_PLLOUT_SEL); - divsel = ((divsel & dsiclk[n].divsel_mask) >> dsiclk[n].divsel_shift); - - if (divsel == PRCM_DSI_PLLOUT_SEL_OFF) - divsel = dsiclk[n].divsel; - - switch (divsel) { - case PRCM_DSI_PLLOUT_SEL_PHI_4: - div *= 2; - case PRCM_DSI_PLLOUT_SEL_PHI_2: - div *= 2; - case PRCM_DSI_PLLOUT_SEL_PHI: - return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK), - PLL_RAW) / div; - default: - return 0; - } -} - -static unsigned long dsiescclk_rate(u8 n) -{ - u32 div; - - div = readl(PRCM_DSITVCLK_DIV); - div = ((div & dsiescclk[n].div_mask) >> (dsiescclk[n].div_shift)); - return clock_rate(PRCMU_TVCLK) / max((u32)1, div); -} - -unsigned long prcmu_clock_rate(u8 clock) -{ - if (clock < PRCMU_NUM_REG_CLOCKS) - return clock_rate(clock); - else if (clock == PRCMU_TIMCLK) - return ROOT_CLOCK_RATE / 16; - else if (clock == PRCMU_SYSCLK) - return ROOT_CLOCK_RATE; - else if (clock == PRCMU_PLLSOC0) - return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW); - else if (clock == PRCMU_PLLSOC1) - return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW); - else if (clock == PRCMU_PLLDDR) - return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW); - else if (clock == PRCMU_PLLDSI) - return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK), - PLL_RAW); - else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) - return dsiclk_rate(clock - PRCMU_DSI0CLK); - else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK)) - return dsiescclk_rate(clock - PRCMU_DSI0ESCCLK); - else - return 0; -} - -static unsigned long clock_source_rate(u32 clk_mgt_val, int branch) -{ - if (clk_mgt_val & PRCM_CLK_MGT_CLK38) - return ROOT_CLOCK_RATE; - clk_mgt_val &= PRCM_CLK_MGT_CLKPLLSW_MASK; - if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC0) - return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, branch); - else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC1) - return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, branch); - else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_DDR) - return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, branch); - else - return 0; -} - -static u32 clock_divider(unsigned long src_rate, unsigned long rate) -{ - u32 div; - - div = (src_rate / rate); - if (div == 0) - return 1; - if (rate < (src_rate / div)) - div++; - return div; -} - -static long round_clock_rate(u8 clock, unsigned long rate) -{ - u32 val; - u32 div; - unsigned long src_rate; - long rounded_rate; - - val = readl(clk_mgt[clock].reg); - src_rate = clock_source_rate((val | clk_mgt[clock].pllsw), - clk_mgt[clock].branch); - div = clock_divider(src_rate, rate); - if (val & PRCM_CLK_MGT_CLK38) { - if (clk_mgt[clock].clk38div) { - if (div > 2) - div = 2; - } else { - div = 1; - } - } else if ((clock == PRCMU_SGACLK) && (div == 3)) { - u64 r = (src_rate * 10); - - (void)do_div(r, 25); - if (r <= rate) - return (unsigned long)r; - } - rounded_rate = (src_rate / min(div, (u32)31)); - - return rounded_rate; -} - -#define MIN_PLL_VCO_RATE 600000000ULL -#define MAX_PLL_VCO_RATE 1680640000ULL - -static long round_plldsi_rate(unsigned long rate) -{ - long rounded_rate = 0; - unsigned long src_rate; - unsigned long rem; - u32 r; - - src_rate = clock_rate(PRCMU_HDMICLK); - rem = rate; - - for (r = 7; (rem > 0) && (r > 0); r--) { - u64 d; - - d = (r * rate); - (void)do_div(d, src_rate); - if (d < 6) - d = 6; - else if (d > 255) - d = 255; - d *= src_rate; - if (((2 * d) < (r * MIN_PLL_VCO_RATE)) || - ((r * MAX_PLL_VCO_RATE) < (2 * d))) - continue; - (void)do_div(d, r); - if (rate < d) { - if (rounded_rate == 0) - rounded_rate = (long)d; - break; - } - if ((rate - d) < rem) { - rem = (rate - d); - rounded_rate = (long)d; - } - } - return rounded_rate; -} - -static long round_dsiclk_rate(unsigned long rate) -{ - u32 div; - unsigned long src_rate; - long rounded_rate; - - src_rate = pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK), - PLL_RAW); - div = clock_divider(src_rate, rate); - rounded_rate = (src_rate / ((div > 2) ? 4 : div)); - - return rounded_rate; -} - -static long round_dsiescclk_rate(unsigned long rate) -{ - u32 div; - unsigned long src_rate; - long rounded_rate; - - src_rate = clock_rate(PRCMU_TVCLK); - div = clock_divider(src_rate, rate); - rounded_rate = (src_rate / min(div, (u32)255)); - - return rounded_rate; -} - -long prcmu_round_clock_rate(u8 clock, unsigned long rate) -{ - if (clock < PRCMU_NUM_REG_CLOCKS) - return round_clock_rate(clock, rate); - else if (clock == PRCMU_PLLDSI) - return round_plldsi_rate(rate); - else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) - return round_dsiclk_rate(rate); - else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK)) - return round_dsiescclk_rate(rate); - else - return (long)prcmu_clock_rate(clock); -} - -static void set_clock_rate(u8 clock, unsigned long rate) -{ - u32 val; - u32 div; - unsigned long src_rate; - unsigned long flags; - - spin_lock_irqsave(&clk_mgt_lock, flags); - - /* Grab the HW semaphore. */ - while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) - cpu_relax(); - - val = readl(clk_mgt[clock].reg); - src_rate = clock_source_rate((val | clk_mgt[clock].pllsw), - clk_mgt[clock].branch); - div = clock_divider(src_rate, rate); - if (val & PRCM_CLK_MGT_CLK38) { - if (clk_mgt[clock].clk38div) { - if (div > 1) - val |= PRCM_CLK_MGT_CLK38DIV; - else - val &= ~PRCM_CLK_MGT_CLK38DIV; - } - } else if (clock == PRCMU_SGACLK) { - val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK | - PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN); - if (div == 3) { - u64 r = (src_rate * 10); - - (void)do_div(r, 25); - if (r <= rate) { - val |= PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN; - div = 0; - } - } - val |= min(div, (u32)31); - } else { - val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK; - val |= min(div, (u32)31); - } - writel(val, clk_mgt[clock].reg); - - /* Release the HW semaphore. */ - writel(0, PRCM_SEM); - - spin_unlock_irqrestore(&clk_mgt_lock, flags); -} - -static int set_plldsi_rate(unsigned long rate) -{ - unsigned long src_rate; - unsigned long rem; - u32 pll_freq = 0; - u32 r; - - src_rate = clock_rate(PRCMU_HDMICLK); - rem = rate; - - for (r = 7; (rem > 0) && (r > 0); r--) { - u64 d; - u64 hwrate; - - d = (r * rate); - (void)do_div(d, src_rate); - if (d < 6) - d = 6; - else if (d > 255) - d = 255; - hwrate = (d * src_rate); - if (((2 * hwrate) < (r * MIN_PLL_VCO_RATE)) || - ((r * MAX_PLL_VCO_RATE) < (2 * hwrate))) - continue; - (void)do_div(hwrate, r); - if (rate < hwrate) { - if (pll_freq == 0) - pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) | - (r << PRCM_PLL_FREQ_R_SHIFT)); - break; - } - if ((rate - hwrate) < rem) { - rem = (rate - hwrate); - pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) | - (r << PRCM_PLL_FREQ_R_SHIFT)); - } - } - if (pll_freq == 0) - return -EINVAL; - - pll_freq |= (1 << PRCM_PLL_FREQ_N_SHIFT); - writel(pll_freq, PRCM_PLLDSI_FREQ); - - return 0; -} - -static void set_dsiclk_rate(u8 n, unsigned long rate) -{ - u32 val; - u32 div; - - div = clock_divider(pll_rate(PRCM_PLLDSI_FREQ, - clock_rate(PRCMU_HDMICLK), PLL_RAW), rate); - - dsiclk[n].divsel = (div == 1) ? PRCM_DSI_PLLOUT_SEL_PHI : - (div == 2) ? PRCM_DSI_PLLOUT_SEL_PHI_2 : - /* else */ PRCM_DSI_PLLOUT_SEL_PHI_4; - - val = readl(PRCM_DSI_PLLOUT_SEL); - val &= ~dsiclk[n].divsel_mask; - val |= (dsiclk[n].divsel << dsiclk[n].divsel_shift); - writel(val, PRCM_DSI_PLLOUT_SEL); -} - -static void set_dsiescclk_rate(u8 n, unsigned long rate) -{ - u32 val; - u32 div; - - div = clock_divider(clock_rate(PRCMU_TVCLK), rate); - val = readl(PRCM_DSITVCLK_DIV); - val &= ~dsiescclk[n].div_mask; - val |= (min(div, (u32)255) << dsiescclk[n].div_shift); - writel(val, PRCM_DSITVCLK_DIV); -} - -int prcmu_set_clock_rate(u8 clock, unsigned long rate) -{ - if (clock < PRCMU_NUM_REG_CLOCKS) - set_clock_rate(clock, rate); - else if (clock == PRCMU_PLLDSI) - return set_plldsi_rate(rate); - else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) - set_dsiclk_rate((clock - PRCMU_DSI0CLK), rate); - else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK)) - set_dsiescclk_rate((clock - PRCMU_DSI0ESCCLK), rate); - return 0; -} - -int db8500_prcmu_config_esram0_deep_sleep(u8 state) -{ - if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) || - (state < ESRAM0_DEEP_SLEEP_STATE_OFF)) - return -EINVAL; - - mutex_lock(&mb4_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) - cpu_relax(); - - writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); - writeb(((DDR_PWR_STATE_OFFHIGHLAT << 4) | DDR_PWR_STATE_ON), - (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE)); - writeb(DDR_PWR_STATE_ON, - (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE)); - writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST)); - - writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb4_transfer.work); - - mutex_unlock(&mb4_transfer.lock); - - return 0; -} - -int db8500_prcmu_config_hotdog(u8 threshold) -{ - mutex_lock(&mb4_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) - cpu_relax(); - - writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD)); - writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); - - writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb4_transfer.work); - - mutex_unlock(&mb4_transfer.lock); - - return 0; -} - -int db8500_prcmu_config_hotmon(u8 low, u8 high) -{ - mutex_lock(&mb4_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) - cpu_relax(); - - writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW)); - writeb(high, (tcdm_base + PRCM_REQ_MB4_HOTMON_HIGH)); - writeb((HOTMON_CONFIG_LOW | HOTMON_CONFIG_HIGH), - (tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG)); - writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); - - writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb4_transfer.work); - - mutex_unlock(&mb4_transfer.lock); - - return 0; -} - -static int config_hot_period(u16 val) -{ - mutex_lock(&mb4_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) - cpu_relax(); - - writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD)); - writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); - - writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb4_transfer.work); - - mutex_unlock(&mb4_transfer.lock); - - return 0; -} - -int db8500_prcmu_start_temp_sense(u16 cycles32k) -{ - if (cycles32k == 0xFFFF) - return -EINVAL; - - return config_hot_period(cycles32k); -} - -int db8500_prcmu_stop_temp_sense(void) -{ - return config_hot_period(0xFFFF); -} - -static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3) -{ - - mutex_lock(&mb4_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) - cpu_relax(); - - writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0)); - writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1)); - writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2)); - writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3)); - - writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); - - writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb4_transfer.work); - - mutex_unlock(&mb4_transfer.lock); - - return 0; - -} - -int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off) -{ - BUG_ON(num == 0 || num > 0xf); - return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0, - sleep_auto_off ? A9WDOG_AUTO_OFF_EN : - A9WDOG_AUTO_OFF_DIS); -} - -int db8500_prcmu_enable_a9wdog(u8 id) -{ - return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0); -} - -int db8500_prcmu_disable_a9wdog(u8 id) -{ - return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0); -} - -int db8500_prcmu_kick_a9wdog(u8 id) -{ - return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0); -} - -/* - * timeout is 28 bit, in ms. - */ -int db8500_prcmu_load_a9wdog(u8 id, u32 timeout) -{ - return prcmu_a9wdog(MB4H_A9WDOG_LOAD, - (id & A9WDOG_ID_MASK) | - /* - * Put the lowest 28 bits of timeout at - * offset 4. Four first bits are used for id. - */ - (u8)((timeout << 4) & 0xf0), - (u8)((timeout >> 4) & 0xff), - (u8)((timeout >> 12) & 0xff), - (u8)((timeout >> 20) & 0xff)); -} - -/** - * prcmu_abb_read() - Read register value(s) from the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The read out value(s). - * @size: The number of registers to read. - * - * Reads register value(s) from the ABB. - * @size has to be 1 for the current firmware version. - */ -int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) -{ - int r; - - if (size != 1) - return -EINVAL; - - mutex_lock(&mb5_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - - writeb(0, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB5)); - writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); - writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); - writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); - writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - - if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", - __func__); - r = -EIO; - } else { - r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); - } - - if (!r) - *value = mb5_transfer.ack.value; - - mutex_unlock(&mb5_transfer.lock); - - return r; -} - -/** - * prcmu_abb_write_masked() - Write masked register value(s) to the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The value(s) to write. - * @mask: The mask(s) to use. - * @size: The number of registers to write. - * - * Writes masked register value(s) to the ABB. - * For each @value, only the bits set to 1 in the corresponding @mask - * will be written. The other bits are not changed. - * @size has to be 1 for the current firmware version. - */ -int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask, u8 size) -{ - int r; - - if (size != 1) - return -EINVAL; - - mutex_lock(&mb5_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - - writeb(~*mask, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB5)); - writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); - writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); - writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); - writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - - if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", - __func__); - r = -EIO; - } else { - r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); - } - - mutex_unlock(&mb5_transfer.lock); - - return r; -} - -/** - * prcmu_abb_write() - Write register value(s) to the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The value(s) to write. - * @size: The number of registers to write. - * - * Writes register value(s) to the ABB. - * @size has to be 1 for the current firmware version. - */ -int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) -{ - u8 mask = ~0; - - return prcmu_abb_write_masked(slave, reg, value, &mask, size); -} - -/** - * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem - */ -void prcmu_ac_wake_req(void) -{ - u32 val; - u32 status; - - mutex_lock(&mb0_transfer.ac_wake_lock); - - val = readl(PRCM_HOSTACCESS_REQ); - if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ) - goto unlock_and_return; - - atomic_set(&ac_wake_req_state, 1); - -retry: - writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ); - - if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, - msecs_to_jiffies(5000))) { - pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", - __func__); - goto unlock_and_return; - } - - /* - * The modem can generate an AC_WAKE_ACK, and then still go to sleep. - * As a workaround, we wait, and then check that the modem is indeed - * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS - * register, which may not be the whole truth). - */ - udelay(400); - status = (readl(PRCM_MOD_AWAKE_STATUS) & BITS(0, 2)); - if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE | - PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) { - pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n", - __func__, status); - udelay(1200); - writel(val, PRCM_HOSTACCESS_REQ); - if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work, - msecs_to_jiffies(5000))) - goto retry; - pr_crit("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n", - __func__); - } - -unlock_and_return: - mutex_unlock(&mb0_transfer.ac_wake_lock); -} - -/** - * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem - */ -void prcmu_ac_sleep_req() -{ - u32 val; - - mutex_lock(&mb0_transfer.ac_wake_lock); - - val = readl(PRCM_HOSTACCESS_REQ); - if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)) - goto unlock_and_return; - - writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), - PRCM_HOSTACCESS_REQ); - - if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, - msecs_to_jiffies(5000))) { - pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", - __func__); - } - - atomic_set(&ac_wake_req_state, 0); - -unlock_and_return: - mutex_unlock(&mb0_transfer.ac_wake_lock); -} - -bool db8500_prcmu_is_ac_wake_requested(void) -{ - return (atomic_read(&ac_wake_req_state) != 0); -} - -/** - * db8500_prcmu_system_reset - System reset - * - * Saves the reset reason code and then sets the APE_SOFTRST register which - * fires interrupt to fw - */ -void db8500_prcmu_system_reset(u16 reset_code) -{ - writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON)); - writel(1, PRCM_APE_SOFTRST); -} - -/** - * db8500_prcmu_get_reset_code - Retrieve SW reset reason code - * - * Retrieves the reset reason code stored by prcmu_system_reset() before - * last restart. - */ -u16 db8500_prcmu_get_reset_code(void) -{ - return readw(tcdm_base + PRCM_SW_RST_REASON); -} - -/** - * db8500_prcmu_reset_modem - ask the PRCMU to reset modem - */ -void db8500_prcmu_modem_reset(void) -{ - mutex_lock(&mb1_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - - /* - * No need to check return from PRCMU as modem should go in reset state - * This state is already managed by upper layer - */ - - mutex_unlock(&mb1_transfer.lock); -} - -static void ack_dbb_wakeup(void) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) - cpu_relax(); - - writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); - writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); -} - -static inline void print_unknown_header_warning(u8 n, u8 header) -{ - pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", - header, n); -} - -static bool read_mailbox_0(void) -{ - bool r; - u32 ev; - unsigned int n; - u8 header; - - header = readb(tcdm_base + PRCM_MBOX_HEADER_ACK_MB0); - switch (header) { - case MB0H_WAKEUP_EXE: - case MB0H_WAKEUP_SLEEP: - if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) - ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_1_8500); - else - ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_0_8500); - - if (ev & (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK)) - complete(&mb0_transfer.ac_wake_work); - if (ev & WAKEUP_BIT_SYSCLK_OK) - complete(&mb3_transfer.sysclk_work); - - ev &= mb0_transfer.req.dbb_irqs; - - for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { - if (ev & prcmu_irq_bit[n]) - generic_handle_irq(IRQ_PRCMU_BASE + n); - } - r = true; - break; - default: - print_unknown_header_warning(0, header); - r = false; - break; - } - writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); - return r; -} - -static bool read_mailbox_1(void) -{ - mb1_transfer.ack.header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1); - mb1_transfer.ack.arm_opp = readb(tcdm_base + - PRCM_ACK_MB1_CURRENT_ARM_OPP); - mb1_transfer.ack.ape_opp = readb(tcdm_base + - PRCM_ACK_MB1_CURRENT_APE_OPP); - mb1_transfer.ack.ape_voltage_status = readb(tcdm_base + - PRCM_ACK_MB1_APE_VOLTAGE_STATUS); - writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); - complete(&mb1_transfer.work); - return false; -} - -static bool read_mailbox_2(void) -{ - mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS); - writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); - complete(&mb2_transfer.work); - return false; -} - -static bool read_mailbox_3(void) -{ - writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_4(void) -{ - u8 header; - bool do_complete = true; - - header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB4); - switch (header) { - case MB4H_MEM_ST: - case MB4H_HOTDOG: - case MB4H_HOTMON: - case MB4H_HOT_PERIOD: - case MB4H_A9WDOG_CONF: - case MB4H_A9WDOG_EN: - case MB4H_A9WDOG_DIS: - case MB4H_A9WDOG_LOAD: - case MB4H_A9WDOG_KICK: - break; - default: - print_unknown_header_warning(4, header); - do_complete = false; - break; - } - - writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); - - if (do_complete) - complete(&mb4_transfer.work); - - return false; -} - -static bool read_mailbox_5(void) -{ - mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS); - mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL); - writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); - complete(&mb5_transfer.work); - return false; -} - -static bool read_mailbox_6(void) -{ - writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); - return false; -} - -static bool read_mailbox_7(void) -{ - writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); - return false; -} - -static bool (* const read_mailbox[NUM_MB])(void) = { - read_mailbox_0, - read_mailbox_1, - read_mailbox_2, - read_mailbox_3, - read_mailbox_4, - read_mailbox_5, - read_mailbox_6, - read_mailbox_7 -}; - -static irqreturn_t prcmu_irq_handler(int irq, void *data) -{ - u32 bits; - u8 n; - irqreturn_t r; - - bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); - if (unlikely(!bits)) - return IRQ_NONE; - - r = IRQ_HANDLED; - for (n = 0; bits; n++) { - if (bits & MBOX_BIT(n)) { - bits -= MBOX_BIT(n); - if (read_mailbox[n]()) - r = IRQ_WAKE_THREAD; - } - } - return r; -} - -static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) -{ - ack_dbb_wakeup(); - return IRQ_HANDLED; -} - -static void prcmu_mask_work(struct work_struct *work) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.lock, flags); - - config_wakeups(); - - spin_unlock_irqrestore(&mb0_transfer.lock, flags); -} - -static void prcmu_irq_mask(struct irq_data *d) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); - - mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; - - spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); - - if (d->irq != IRQ_PRCMU_CA_SLEEP) - schedule_work(&mb0_transfer.mask_work); -} - -static void prcmu_irq_unmask(struct irq_data *d) -{ - unsigned long flags; - - spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); - - mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; - - spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); - - if (d->irq != IRQ_PRCMU_CA_SLEEP) - schedule_work(&mb0_transfer.mask_work); -} - -static void noop(struct irq_data *d) -{ -} - -static struct irq_chip prcmu_irq_chip = { - .name = "prcmu", - .irq_disable = prcmu_irq_mask, - .irq_ack = noop, - .irq_mask = prcmu_irq_mask, - .irq_unmask = prcmu_irq_unmask, -}; - -static char *fw_project_name(u8 project) -{ - switch (project) { - case PRCMU_FW_PROJECT_U8500: - return "U8500"; - case PRCMU_FW_PROJECT_U8500_C2: - return "U8500 C2"; - case PRCMU_FW_PROJECT_U9500: - return "U9500"; - case PRCMU_FW_PROJECT_U9500_C2: - return "U9500 C2"; - case PRCMU_FW_PROJECT_U8520: - return "U8520"; - case PRCMU_FW_PROJECT_U8420: - return "U8420"; - default: - return "Unknown"; - } -} - -void __init db8500_prcmu_early_init(void) -{ - unsigned int i; - if (cpu_is_u8500v2()) { - void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); - - if (tcpm_base != NULL) { - u32 version; - version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET); - fw_info.version.project = version & 0xFF; - fw_info.version.api_version = (version >> 8) & 0xFF; - fw_info.version.func_version = (version >> 16) & 0xFF; - fw_info.version.errata = (version >> 24) & 0xFF; - fw_info.valid = true; - pr_info("PRCMU firmware: %s, version %d.%d.%d\n", - fw_project_name(fw_info.version.project), - (version >> 8) & 0xFF, (version >> 16) & 0xFF, - (version >> 24) & 0xFF); - iounmap(tcpm_base); - } - - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); - } else { - pr_err("prcmu: Unsupported chip version\n"); - BUG(); - } - - spin_lock_init(&mb0_transfer.lock); - spin_lock_init(&mb0_transfer.dbb_irqs_lock); - mutex_init(&mb0_transfer.ac_wake_lock); - init_completion(&mb0_transfer.ac_wake_work); - mutex_init(&mb1_transfer.lock); - init_completion(&mb1_transfer.work); - mb1_transfer.ape_opp = APE_NO_CHANGE; - mutex_init(&mb2_transfer.lock); - init_completion(&mb2_transfer.work); - spin_lock_init(&mb2_transfer.auto_pm_lock); - spin_lock_init(&mb3_transfer.lock); - mutex_init(&mb3_transfer.sysclk_lock); - init_completion(&mb3_transfer.sysclk_work); - mutex_init(&mb4_transfer.lock); - init_completion(&mb4_transfer.work); - mutex_init(&mb5_transfer.lock); - init_completion(&mb5_transfer.work); - - INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); - - /* Initalize irqs. */ - for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) { - unsigned int irq; - - irq = IRQ_PRCMU_BASE + i; - irq_set_chip_and_handler(irq, &prcmu_irq_chip, - handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); - } -} - -static void __init init_prcm_registers(void) -{ - u32 val; - - val = readl(PRCM_A9PL_FORCE_CLKEN); - val &= ~(PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN | - PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN); - writel(val, (PRCM_A9PL_FORCE_CLKEN)); -} - -/* - * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC - */ -static struct regulator_consumer_supply db8500_vape_consumers[] = { - REGULATOR_SUPPLY("v-ape", NULL), - REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"), - REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), - REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), - REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), - /* "v-mmc" changed to "vcore" in the mainline kernel */ - REGULATOR_SUPPLY("vcore", "sdi0"), - REGULATOR_SUPPLY("vcore", "sdi1"), - REGULATOR_SUPPLY("vcore", "sdi2"), - REGULATOR_SUPPLY("vcore", "sdi3"), - REGULATOR_SUPPLY("vcore", "sdi4"), - REGULATOR_SUPPLY("v-dma", "dma40.0"), - REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"), - /* "v-uart" changed to "vcore" in the mainline kernel */ - REGULATOR_SUPPLY("vcore", "uart0"), - REGULATOR_SUPPLY("vcore", "uart1"), - REGULATOR_SUPPLY("vcore", "uart2"), - REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"), - REGULATOR_SUPPLY("v-hsi", "ste_hsi.0"), -}; - -static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { - REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"), - /* AV8100 regulator */ - REGULATOR_SUPPLY("hdmi_1v8", "0-0070"), -}; - -static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { - REGULATOR_SUPPLY("vsupply", "b2r2_bus"), - REGULATOR_SUPPLY("vsupply", "mcde"), -}; - -/* SVA MMDSP regulator switch */ -static struct regulator_consumer_supply db8500_svammdsp_consumers[] = { - REGULATOR_SUPPLY("sva-mmdsp", "cm_control"), -}; - -/* SVA pipe regulator switch */ -static struct regulator_consumer_supply db8500_svapipe_consumers[] = { - REGULATOR_SUPPLY("sva-pipe", "cm_control"), -}; - -/* SIA MMDSP regulator switch */ -static struct regulator_consumer_supply db8500_siammdsp_consumers[] = { - REGULATOR_SUPPLY("sia-mmdsp", "cm_control"), -}; - -/* SIA pipe regulator switch */ -static struct regulator_consumer_supply db8500_siapipe_consumers[] = { - REGULATOR_SUPPLY("sia-pipe", "cm_control"), -}; - -static struct regulator_consumer_supply db8500_sga_consumers[] = { - REGULATOR_SUPPLY("v-mali", NULL), -}; - -/* ESRAM1 and 2 regulator switch */ -static struct regulator_consumer_supply db8500_esram12_consumers[] = { - REGULATOR_SUPPLY("esram12", "cm_control"), -}; - -/* ESRAM3 and 4 regulator switch */ -static struct regulator_consumer_supply db8500_esram34_consumers[] = { - REGULATOR_SUPPLY("v-esram34", "mcde"), - REGULATOR_SUPPLY("esram34", "cm_control"), - REGULATOR_SUPPLY("lcla_esram", "dma40.0"), -}; - -static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { - [DB8500_REGULATOR_VAPE] = { - .constraints = { - .name = "db8500-vape", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .always_on = true, - }, - .consumer_supplies = db8500_vape_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), - }, - [DB8500_REGULATOR_VARM] = { - .constraints = { - .name = "db8500-varm", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_VMODEM] = { - .constraints = { - .name = "db8500-vmodem", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_VPLL] = { - .constraints = { - .name = "db8500-vpll", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_VSMPS1] = { - .constraints = { - .name = "db8500-vsmps1", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_VSMPS2] = { - .constraints = { - .name = "db8500-vsmps2", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_vsmps2_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers), - }, - [DB8500_REGULATOR_VSMPS3] = { - .constraints = { - .name = "db8500-vsmps3", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_VRF1] = { - .constraints = { - .name = "db8500-vrf1", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { - /* dependency to u8500-vape is handled outside regulator framework */ - .constraints = { - .name = "db8500-sva-mmdsp", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_svammdsp_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_svammdsp_consumers), - }, - [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { - .constraints = { - /* "ret" means "retention" */ - .name = "db8500-sva-mmdsp-ret", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_SWITCH_SVAPIPE] = { - /* dependency to u8500-vape is handled outside regulator framework */ - .constraints = { - .name = "db8500-sva-pipe", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_svapipe_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_svapipe_consumers), - }, - [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { - /* dependency to u8500-vape is handled outside regulator framework */ - .constraints = { - .name = "db8500-sia-mmdsp", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_siammdsp_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_siammdsp_consumers), - }, - [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { - .constraints = { - .name = "db8500-sia-mmdsp-ret", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_SWITCH_SIAPIPE] = { - /* dependency to u8500-vape is handled outside regulator framework */ - .constraints = { - .name = "db8500-sia-pipe", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_siapipe_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_siapipe_consumers), - }, - [DB8500_REGULATOR_SWITCH_SGA] = { - .supply_regulator = "db8500-vape", - .constraints = { - .name = "db8500-sga", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_sga_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_sga_consumers), - - }, - [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { - .supply_regulator = "db8500-vape", - .constraints = { - .name = "db8500-b2r2-mcde", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_b2r2_mcde_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers), - }, - [DB8500_REGULATOR_SWITCH_ESRAM12] = { - /* - * esram12 is set in retention and supplied by Vsafe when Vape is off, - * no need to hold Vape - */ - .constraints = { - .name = "db8500-esram12", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_esram12_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_esram12_consumers), - }, - [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { - .constraints = { - .name = "db8500-esram12-ret", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, - [DB8500_REGULATOR_SWITCH_ESRAM34] = { - /* - * esram34 is set in retention and supplied by Vsafe when Vape is off, - * no need to hold Vape - */ - .constraints = { - .name = "db8500-esram34", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = db8500_esram34_consumers, - .num_consumer_supplies = ARRAY_SIZE(db8500_esram34_consumers), - }, - [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { - .constraints = { - .name = "db8500-esram34-ret", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - }, -}; - -static struct mfd_cell db8500_prcmu_devs[] = { - { - .name = "db8500-prcmu-regulators", - .platform_data = &db8500_regulators, - .pdata_size = sizeof(db8500_regulators), - }, - { - .name = "cpufreq-u8500", - }, -}; - -/** - * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic - * - */ -static int __init db8500_prcmu_probe(struct platform_device *pdev) -{ - int err = 0; - - if (ux500_is_svp()) - return -ENODEV; - - init_prcm_registers(); - - /* Clean up the mailbox interrupts after pre-kernel code. */ - writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); - - err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, - prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); - if (err < 0) { - pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); - err = -EBUSY; - goto no_irq_return; - } - - if (cpu_is_u8500v20_or_later()) - prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); - - err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, - ARRAY_SIZE(db8500_prcmu_devs), NULL, - 0); - - if (err) - pr_err("prcmu: Failed to add subdevices\n"); - else - pr_info("DB8500 PRCMU initialized\n"); - -no_irq_return: - return err; -} - -static struct platform_driver db8500_prcmu_driver = { - .driver = { - .name = "db8500-prcmu", - .owner = THIS_MODULE, - }, -}; - -static int __init db8500_prcmu_init(void) -{ - return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe); -} - -arch_initcall(db8500_prcmu_init); - -MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com>"); -MODULE_DESCRIPTION("DB8500 PRCM Unit driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/dbx500-prcmu-regs.h b/ANDROID_3.4.5/drivers/mfd/dbx500-prcmu-regs.h deleted file mode 100644 index 3a0bf91d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/dbx500-prcmu-regs.h +++ /dev/null @@ -1,250 +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 <mach/hardware.h> - -#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) - -#define PRCM_CLK_MGT(_offset) (void __iomem *)(IO_ADDRESS(U8500_PRCMU_BASE) \ - + _offset) -#define PRCM_ACLK_MGT PRCM_CLK_MGT(0x004) -#define PRCM_SVACLK_MGT PRCM_CLK_MGT(0x008) -#define PRCM_SIACLK_MGT PRCM_CLK_MGT(0x00C) -#define PRCM_SGACLK_MGT PRCM_CLK_MGT(0x014) -#define PRCM_UARTCLK_MGT PRCM_CLK_MGT(0x018) -#define PRCM_MSP02CLK_MGT PRCM_CLK_MGT(0x01C) -#define PRCM_I2CCLK_MGT PRCM_CLK_MGT(0x020) -#define PRCM_SDMMCCLK_MGT PRCM_CLK_MGT(0x024) -#define PRCM_SLIMCLK_MGT PRCM_CLK_MGT(0x028) -#define PRCM_PER1CLK_MGT PRCM_CLK_MGT(0x02C) -#define PRCM_PER2CLK_MGT PRCM_CLK_MGT(0x030) -#define PRCM_PER3CLK_MGT PRCM_CLK_MGT(0x034) -#define PRCM_PER5CLK_MGT PRCM_CLK_MGT(0x038) -#define PRCM_PER6CLK_MGT PRCM_CLK_MGT(0x03C) -#define PRCM_PER7CLK_MGT PRCM_CLK_MGT(0x040) -#define PRCM_LCDCLK_MGT PRCM_CLK_MGT(0x044) -#define PRCM_BMLCLK_MGT PRCM_CLK_MGT(0x04C) -#define PRCM_HSITXCLK_MGT PRCM_CLK_MGT(0x050) -#define PRCM_HSIRXCLK_MGT PRCM_CLK_MGT(0x054) -#define PRCM_HDMICLK_MGT PRCM_CLK_MGT(0x058) -#define PRCM_APEATCLK_MGT PRCM_CLK_MGT(0x05C) -#define PRCM_APETRACECLK_MGT PRCM_CLK_MGT(0x060) -#define PRCM_MCDECLK_MGT PRCM_CLK_MGT(0x064) -#define PRCM_IPI2CCLK_MGT PRCM_CLK_MGT(0x068) -#define PRCM_DSIALTCLK_MGT PRCM_CLK_MGT(0x06C) -#define PRCM_DMACLK_MGT PRCM_CLK_MGT(0x074) -#define PRCM_B2R2CLK_MGT PRCM_CLK_MGT(0x078) -#define PRCM_TVCLK_MGT PRCM_CLK_MGT(0x07C) -#define PRCM_UNIPROCLK_MGT PRCM_CLK_MGT(0x278) -#define PRCM_SSPCLK_MGT PRCM_CLK_MGT(0x280) -#define PRCM_RNGCLK_MGT PRCM_CLK_MGT(0x284) -#define PRCM_UICCCLK_MGT PRCM_CLK_MGT(0x27C) -#define PRCM_MSP1CLK_MGT PRCM_CLK_MGT(0x288) - -#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) -#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f -#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf - -#define PRCM_PLLARM_LOCKP (_PRCMU_BASE + 0x0a8) -#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 - -#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) -#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 - -#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) -#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 -#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 - -#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_SET (_PRCMU_BASE + 0x1f0) -#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) -#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 */ -#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) -#define PRCM_ARM_WFI_STANDBY_WFI0 0x08 -#define PRCM_ARM_WFI_STANDBY_WFI1 0x10 -#define PRCM_IOCR (_PRCMU_BASE + 0x310) -#define PRCM_IOCR_IOFORCE 0x1 - -/* CPU mailbox registers */ -#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) -#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) -#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) - -/* Dual A9 core interrupt management unit registers */ -#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) -#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1 - -#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) -#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) -#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) -#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) -#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) -#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) -#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) -#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) -#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) -#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) - -#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) -#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 -#define ARM_WAKEUP_MODEM 0x1 - -#define PRCM_ARM_IT1_CLR (_PRCMU_BASE + 0x48C) -#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) -#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_ITSTATUS1 (_PRCMU_BASE + 0x150) -#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) -#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) -#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) -#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) -#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) -#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) - -/* System reset register */ -#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) - -/* Level shifter and clamp control registers */ -#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) -#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) - -#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP BIT(11) -#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI BIT(22) - -/* PRCMU clock/PLL/reset registers */ -#define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) -#define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) -#define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) -#define PRCM_PLL_FREQ_D_SHIFT 0 -#define PRCM_PLL_FREQ_D_MASK BITS(0, 7) -#define PRCM_PLL_FREQ_N_SHIFT 8 -#define PRCM_PLL_FREQ_N_MASK BITS(8, 13) -#define PRCM_PLL_FREQ_R_SHIFT 16 -#define PRCM_PLL_FREQ_R_MASK BITS(16, 18) -#define PRCM_PLL_FREQ_SELDIV2 BIT(24) -#define PRCM_PLL_FREQ_DIV2EN BIT(25) - -#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) -#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) -#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) -#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) -#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) -#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) -#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) -#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) - -#define PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE BIT(0) - -#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 BIT(0) -#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3 BIT(1) - -#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT 0 -#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK BITS(0, 2) -#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT 8 -#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK BITS(8, 10) - -#define PRCM_DSI_PLLOUT_SEL_OFF 0 -#define PRCM_DSI_PLLOUT_SEL_PHI 1 -#define PRCM_DSI_PLLOUT_SEL_PHI_2 2 -#define PRCM_DSI_PLLOUT_SEL_PHI_4 3 - -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT 0 -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK BITS(0, 7) -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT 8 -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK BITS(8, 15) -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT 16 -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK BITS(16, 23) -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN BIT(24) -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN BIT(25) -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN BIT(26) - -#define PRCM_APE_RESETN_DSIPLL_RESETN BIT(14) - -#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 */ -#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) -#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) - -/* Debug power control unit registers */ -#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) - -/* Miscellaneous unit registers */ -#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) -#define PRCM_GPIOCR (_PRCMU_BASE + 0x138) -#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 -#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 - -/* PRCMU HW semaphore */ -#define PRCM_SEM (_PRCMU_BASE + 0x400) -#define PRCM_SEM_PRCM_SEM BIT(0) - -#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_SOC0 BIT(5) -#define PRCM_CLK_MGT_CLKPLLSW_SOC1 BIT(6) -#define PRCM_CLK_MGT_CLKPLLSW_DDR BIT(7) -#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) -#define PRCM_CLK_MGT_CLKEN BIT(8) -#define PRCM_CLK_MGT_CLK38 BIT(9) -#define PRCM_CLK_MGT_CLK38DIV BIT(11) -#define PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN BIT(12) - -/* 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 */ diff --git a/ANDROID_3.4.5/drivers/mfd/dm355evm_msp.c b/ANDROID_3.4.5/drivers/mfd/dm355evm_msp.c deleted file mode 100644 index 7710227d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/dm355evm_msp.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * dm355evm_msp.c - driver for MSP430 firmware on DM355EVM board - * - * Copyright (C) 2008 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/module.h> -#include <linux/err.h> -#include <linux/gpio.h> -#include <linux/leds.h> -#include <linux/i2c.h> -#include <linux/i2c/dm355evm_msp.h> - - -/* - * The DM355 is a DaVinci chip with video support but no C64+ DSP. Its - * EVM board has an MSP430 programmed with firmware for various board - * support functions. This driver exposes some of them directly, and - * supports other drivers (e.g. RTC, input) for more complex access. - * - * Because this firmware is entirely board-specific, this file embeds - * knowledge that would be passed as platform_data in a generic driver. - * - * This driver was tested with firmware revision A4. - */ - -#if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE) -#define msp_has_keyboard() true -#else -#define msp_has_keyboard() false -#endif - -#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) -#define msp_has_leds() true -#else -#define msp_has_leds() false -#endif - -#if defined(CONFIG_RTC_DRV_DM355EVM) || defined(CONFIG_RTC_DRV_DM355EVM_MODULE) -#define msp_has_rtc() true -#else -#define msp_has_rtc() false -#endif - -#if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE) -#define msp_has_tvp() true -#else -#define msp_has_tvp() false -#endif - - -/*----------------------------------------------------------------------*/ - -/* REVISIT for paranoia's sake, retry reads/writes on error */ - -static struct i2c_client *msp430; - -/** - * dm355evm_msp_write - Writes a register in dm355evm_msp - * @value: the value to be written - * @reg: register address - * - * Returns result of operation - 0 is success, else negative errno - */ -int dm355evm_msp_write(u8 value, u8 reg) -{ - return i2c_smbus_write_byte_data(msp430, reg, value); -} -EXPORT_SYMBOL(dm355evm_msp_write); - -/** - * dm355evm_msp_read - Reads a register from dm355evm_msp - * @reg: register address - * - * Returns result of operation - value, or negative errno - */ -int dm355evm_msp_read(u8 reg) -{ - return i2c_smbus_read_byte_data(msp430, reg); -} -EXPORT_SYMBOL(dm355evm_msp_read); - -/*----------------------------------------------------------------------*/ - -/* - * Many of the msp430 pins are just used as fixed-direction GPIOs. - * We could export a few more of them this way, if we wanted. - */ -#define MSP_GPIO(bit,reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit)) - -static const u8 msp_gpios[] = { - /* eight leds */ - MSP_GPIO(0, LED), MSP_GPIO(1, LED), - MSP_GPIO(2, LED), MSP_GPIO(3, LED), - MSP_GPIO(4, LED), MSP_GPIO(5, LED), - MSP_GPIO(6, LED), MSP_GPIO(7, LED), - /* SW6 and the NTSC/nPAL jumper */ - MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1), - MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1), - MSP_GPIO(4, SWITCH1), - /* switches on MMC/SD sockets */ - /* - * Note: EVMDM355_ECP_VA4.pdf suggests that Bit 2 and 4 should be - * checked for card detection. However on the EVM bit 1 and 3 gives - * this status, for 0 and 1 instance respectively. The pdf also - * suggests that Bit 1 and 3 should be checked for write protection. - * However on the EVM bit 2 and 4 gives this status,for 0 and 1 - * instance respectively. - */ - MSP_GPIO(2, SDMMC), MSP_GPIO(1, SDMMC), /* mmc0 WP, nCD */ - MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC), /* mmc1 WP, nCD */ -}; - -#define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3) -#define MSP_GPIO_MASK(offset) BIT(msp_gpios[(offset)] & 0x07) - -static int msp_gpio_in(struct gpio_chip *chip, unsigned offset) -{ - switch (MSP_GPIO_REG(offset)) { - case DM355EVM_MSP_SWITCH1: - case DM355EVM_MSP_SWITCH2: - case DM355EVM_MSP_SDMMC: - return 0; - default: - return -EINVAL; - } -} - -static u8 msp_led_cache; - -static int msp_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - int reg, status; - - reg = MSP_GPIO_REG(offset); - status = dm355evm_msp_read(reg); - if (status < 0) - return status; - if (reg == DM355EVM_MSP_LED) - msp_led_cache = status; - return status & MSP_GPIO_MASK(offset); -} - -static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value) -{ - int mask, bits; - - /* NOTE: there are some other signals that could be - * packaged as output GPIOs, but they aren't as useful - * as the LEDs ... so for now we don't. - */ - if (MSP_GPIO_REG(offset) != DM355EVM_MSP_LED) - return -EINVAL; - - mask = MSP_GPIO_MASK(offset); - bits = msp_led_cache; - - bits &= ~mask; - if (value) - bits |= mask; - msp_led_cache = bits; - - return dm355evm_msp_write(bits, DM355EVM_MSP_LED); -} - -static void msp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - msp_gpio_out(chip, offset, value); -} - -static struct gpio_chip dm355evm_msp_gpio = { - .label = "dm355evm_msp", - .owner = THIS_MODULE, - .direction_input = msp_gpio_in, - .get = msp_gpio_get, - .direction_output = msp_gpio_out, - .set = msp_gpio_set, - .base = -EINVAL, /* dynamic assignment */ - .ngpio = ARRAY_SIZE(msp_gpios), - .can_sleep = true, -}; - -/*----------------------------------------------------------------------*/ - -static struct device *add_child(struct i2c_client *client, const char *name, - void *pdata, unsigned pdata_len, - bool can_wakeup, int irq) -{ - struct platform_device *pdev; - int status; - - pdev = platform_device_alloc(name, -1); - if (!pdev) { - dev_dbg(&client->dev, "can't alloc dev\n"); - status = -ENOMEM; - goto err; - } - - device_init_wakeup(&pdev->dev, can_wakeup); - pdev->dev.parent = &client->dev; - - if (pdata) { - status = platform_device_add_data(pdev, pdata, pdata_len); - if (status < 0) { - dev_dbg(&pdev->dev, "can't add platform_data\n"); - goto err; - } - } - - if (irq) { - struct resource r = { - .start = irq, - .flags = IORESOURCE_IRQ, - }; - - status = platform_device_add_resources(pdev, &r, 1); - if (status < 0) { - dev_dbg(&pdev->dev, "can't add irq\n"); - goto err; - } - } - - status = platform_device_add(pdev); - -err: - if (status < 0) { - platform_device_put(pdev); - dev_err(&client->dev, "can't add %s dev\n", name); - return ERR_PTR(status); - } - return &pdev->dev; -} - -static int add_children(struct i2c_client *client) -{ - static const struct { - int offset; - char *label; - } config_inputs[] = { - /* 8 == right after the LEDs */ - { 8 + 0, "sw6_1", }, - { 8 + 1, "sw6_2", }, - { 8 + 2, "sw6_3", }, - { 8 + 3, "sw6_4", }, - { 8 + 4, "NTSC/nPAL", }, - }; - - struct device *child; - int status; - int i; - - /* GPIO-ish stuff */ - dm355evm_msp_gpio.dev = &client->dev; - status = gpiochip_add(&dm355evm_msp_gpio); - if (status < 0) - return status; - - /* LED output */ - if (msp_has_leds()) { -#define GPIO_LED(l) .name = l, .active_low = true - static struct gpio_led evm_leds[] = { - { GPIO_LED("dm355evm::ds14"), - .default_trigger = "heartbeat", }, - { GPIO_LED("dm355evm::ds15"), - .default_trigger = "mmc0", }, - { GPIO_LED("dm355evm::ds16"), - /* could also be a CE-ATA drive */ - .default_trigger = "mmc1", }, - { GPIO_LED("dm355evm::ds17"), - .default_trigger = "nand-disk", }, - { GPIO_LED("dm355evm::ds18"), }, - { GPIO_LED("dm355evm::ds19"), }, - { GPIO_LED("dm355evm::ds20"), }, - { GPIO_LED("dm355evm::ds21"), }, - }; -#undef GPIO_LED - - struct gpio_led_platform_data evm_led_data = { - .num_leds = ARRAY_SIZE(evm_leds), - .leds = evm_leds, - }; - - for (i = 0; i < ARRAY_SIZE(evm_leds); i++) - evm_leds[i].gpio = i + dm355evm_msp_gpio.base; - - /* NOTE: these are the only fully programmable LEDs - * on the board, since GPIO-61/ds22 (and many signals - * going to DC7) must be used for AEMIF address lines - * unless the top 1 GB of NAND is unused... - */ - child = add_child(client, "leds-gpio", - &evm_led_data, sizeof(evm_led_data), - false, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* configuration inputs */ - for (i = 0; i < ARRAY_SIZE(config_inputs); i++) { - int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset; - - gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label); - - /* make it easy for userspace to see these */ - gpio_export(gpio, false); - } - - /* MMC/SD inputs -- right after the last config input */ - if (client->dev.platform_data) { - void (*mmcsd_setup)(unsigned) = client->dev.platform_data; - - mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5); - } - - /* RTC is a 32 bit counter, no alarm */ - if (msp_has_rtc()) { - child = add_child(client, "rtc-dm355evm", - NULL, 0, false, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* input from buttons and IR remote (uses the IRQ) */ - if (msp_has_keyboard()) { - child = add_child(client, "dm355evm_keys", - NULL, 0, true, client->irq); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - return 0; -} - -/*----------------------------------------------------------------------*/ - -static void dm355evm_command(unsigned command) -{ - int status; - - status = dm355evm_msp_write(command, DM355EVM_MSP_COMMAND); - if (status < 0) - dev_err(&msp430->dev, "command %d failure %d\n", - command, status); -} - -static void dm355evm_power_off(void) -{ - dm355evm_command(MSP_COMMAND_POWEROFF); -} - -static int dm355evm_msp_remove(struct i2c_client *client) -{ - pm_power_off = NULL; - msp430 = NULL; - return 0; -} - -static int -dm355evm_msp_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - int status; - const char *video = msp_has_tvp() ? "TVP5146" : "imager"; - - if (msp430) - return -EBUSY; - msp430 = client; - - /* display revision status; doubles as sanity check */ - status = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); - if (status < 0) - goto fail; - dev_info(&client->dev, "firmware v.%02X, %s as video-in\n", - status, video); - - /* mux video input: either tvp5146 or some external imager */ - status = dm355evm_msp_write(msp_has_tvp() ? 0 : MSP_VIDEO_IMAGER, - DM355EVM_MSP_VIDEO_IN); - if (status < 0) - dev_warn(&client->dev, "error %d muxing %s as video-in\n", - status, video); - - /* init LED cache, and turn off the LEDs */ - msp_led_cache = 0xff; - dm355evm_msp_write(msp_led_cache, DM355EVM_MSP_LED); - - /* export capabilities we support */ - status = add_children(client); - if (status < 0) - goto fail; - - /* PM hookup */ - pm_power_off = dm355evm_power_off; - - return 0; - -fail: - /* FIXME remove children ... */ - dm355evm_msp_remove(client); - return status; -} - -static const struct i2c_device_id dm355evm_msp_ids[] = { - { "dm355evm_msp", 0 }, - { /* end of list */ }, -}; -MODULE_DEVICE_TABLE(i2c, dm355evm_msp_ids); - -static struct i2c_driver dm355evm_msp_driver = { - .driver.name = "dm355evm_msp", - .id_table = dm355evm_msp_ids, - .probe = dm355evm_msp_probe, - .remove = dm355evm_msp_remove, -}; - -static int __init dm355evm_msp_init(void) -{ - return i2c_add_driver(&dm355evm_msp_driver); -} -subsys_initcall(dm355evm_msp_init); - -static void __exit dm355evm_msp_exit(void) -{ - i2c_del_driver(&dm355evm_msp_driver); -} -module_exit(dm355evm_msp_exit); - -MODULE_DESCRIPTION("Interface to MSP430 firmware on DM355EVM"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ezx-pcap.c b/ANDROID_3.4.5/drivers/mfd/ezx-pcap.c deleted file mode 100644 index 43a76c41..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ezx-pcap.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Driver for Motorola PCAP2 as present in EZX phones - * - * Copyright (C) 2006 Harald Welte <laforge@openezx.org> - * Copyright (C) 2009 Daniel Ribeiro <drwyrm@gmail.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/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mfd/ezx-pcap.h> -#include <linux/spi/spi.h> -#include <linux/gpio.h> -#include <linux/slab.h> - -#define PCAP_ADC_MAXQ 8 -struct pcap_adc_request { - u8 bank; - u8 ch[2]; - u32 flags; - void (*callback)(void *, u16[]); - void *data; -}; - -struct pcap_adc_sync_request { - u16 res[2]; - struct completion completion; -}; - -struct pcap_chip { - struct spi_device *spi; - - /* IO */ - u32 buf; - struct mutex io_mutex; - - /* IRQ */ - unsigned int irq_base; - u32 msr; - struct work_struct isr_work; - struct work_struct msr_work; - struct workqueue_struct *workqueue; - - /* ADC */ - struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ]; - u8 adc_head; - u8 adc_tail; - struct mutex adc_mutex; -}; - -/* IO */ -static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data) -{ - struct spi_transfer t; - struct spi_message m; - int status; - - memset(&t, 0, sizeof t); - spi_message_init(&m); - t.len = sizeof(u32); - spi_message_add_tail(&t, &m); - - pcap->buf = *data; - t.tx_buf = (u8 *) &pcap->buf; - t.rx_buf = (u8 *) &pcap->buf; - status = spi_sync(pcap->spi, &m); - - if (status == 0) - *data = pcap->buf; - - return status; -} - -int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value) -{ - int ret; - - mutex_lock(&pcap->io_mutex); - value &= PCAP_REGISTER_VALUE_MASK; - value |= PCAP_REGISTER_WRITE_OP_BIT - | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); - ret = ezx_pcap_putget(pcap, &value); - mutex_unlock(&pcap->io_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(ezx_pcap_write); - -int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value) -{ - int ret; - - mutex_lock(&pcap->io_mutex); - *value = PCAP_REGISTER_READ_OP_BIT - | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); - - ret = ezx_pcap_putget(pcap, value); - mutex_unlock(&pcap->io_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(ezx_pcap_read); - -int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val) -{ - int ret; - u32 tmp = PCAP_REGISTER_READ_OP_BIT | - (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); - - mutex_lock(&pcap->io_mutex); - ret = ezx_pcap_putget(pcap, &tmp); - if (ret) - goto out_unlock; - - tmp &= (PCAP_REGISTER_VALUE_MASK & ~mask); - tmp |= (val & mask) | PCAP_REGISTER_WRITE_OP_BIT | - (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); - - ret = ezx_pcap_putget(pcap, &tmp); -out_unlock: - mutex_unlock(&pcap->io_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(ezx_pcap_set_bits); - -/* IRQ */ -int irq_to_pcap(struct pcap_chip *pcap, int irq) -{ - return irq - pcap->irq_base; -} -EXPORT_SYMBOL_GPL(irq_to_pcap); - -int pcap_to_irq(struct pcap_chip *pcap, int irq) -{ - return pcap->irq_base + irq; -} -EXPORT_SYMBOL_GPL(pcap_to_irq); - -static void pcap_mask_irq(struct irq_data *d) -{ - struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); - - pcap->msr |= 1 << irq_to_pcap(pcap, d->irq); - queue_work(pcap->workqueue, &pcap->msr_work); -} - -static void pcap_unmask_irq(struct irq_data *d) -{ - struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); - - pcap->msr &= ~(1 << irq_to_pcap(pcap, d->irq)); - queue_work(pcap->workqueue, &pcap->msr_work); -} - -static struct irq_chip pcap_irq_chip = { - .name = "pcap", - .irq_disable = pcap_mask_irq, - .irq_mask = pcap_mask_irq, - .irq_unmask = pcap_unmask_irq, -}; - -static void pcap_msr_work(struct work_struct *work) -{ - struct pcap_chip *pcap = container_of(work, struct pcap_chip, msr_work); - - ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); -} - -static void pcap_isr_work(struct work_struct *work) -{ - struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work); - struct pcap_platform_data *pdata = pcap->spi->dev.platform_data; - u32 msr, isr, int_sel, service; - int irq; - - do { - ezx_pcap_read(pcap, PCAP_REG_MSR, &msr); - ezx_pcap_read(pcap, PCAP_REG_ISR, &isr); - - /* We can't service/ack irqs that are assigned to port 2 */ - if (!(pdata->config & PCAP_SECOND_PORT)) { - ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel); - isr &= ~int_sel; - } - - ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr); - ezx_pcap_write(pcap, PCAP_REG_ISR, isr); - - local_irq_disable(); - service = isr & ~msr; - for (irq = pcap->irq_base; service; service >>= 1, irq++) { - if (service & 1) - generic_handle_irq(irq); - } - local_irq_enable(); - ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); - } while (gpio_get_value(irq_to_gpio(pcap->spi->irq))); -} - -static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - struct pcap_chip *pcap = irq_get_handler_data(irq); - - desc->irq_data.chip->irq_ack(&desc->irq_data); - queue_work(pcap->workqueue, &pcap->isr_work); - return; -} - -/* ADC */ -void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits) -{ - u32 tmp; - - mutex_lock(&pcap->adc_mutex); - ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); - tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); - tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); - ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); - mutex_unlock(&pcap->adc_mutex); -} -EXPORT_SYMBOL_GPL(pcap_set_ts_bits); - -static void pcap_disable_adc(struct pcap_chip *pcap) -{ - u32 tmp; - - ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); - tmp &= ~(PCAP_ADC_ADEN|PCAP_ADC_BATT_I_ADC|PCAP_ADC_BATT_I_POLARITY); - ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); -} - -static void pcap_adc_trigger(struct pcap_chip *pcap) -{ - u32 tmp; - u8 head; - - mutex_lock(&pcap->adc_mutex); - head = pcap->adc_head; - if (!pcap->adc_queue[head]) { - /* queue is empty, save power */ - pcap_disable_adc(pcap); - mutex_unlock(&pcap->adc_mutex); - return; - } - /* start conversion on requested bank, save TS_M bits */ - ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); - tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); - tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN; - - if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1) - tmp |= PCAP_ADC_AD_SEL1; - - ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); - mutex_unlock(&pcap->adc_mutex); - ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC); -} - -static irqreturn_t pcap_adc_irq(int irq, void *_pcap) -{ - struct pcap_chip *pcap = _pcap; - struct pcap_adc_request *req; - u16 res[2]; - u32 tmp; - - mutex_lock(&pcap->adc_mutex); - req = pcap->adc_queue[pcap->adc_head]; - - if (WARN(!req, "adc irq without pending request\n")) { - mutex_unlock(&pcap->adc_mutex); - return IRQ_HANDLED; - } - - /* read requested channels results */ - ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); - tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK); - tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT); - tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT); - ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); - ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp); - res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT; - res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT; - - pcap->adc_queue[pcap->adc_head] = NULL; - pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1); - mutex_unlock(&pcap->adc_mutex); - - /* pass the results and release memory */ - req->callback(req->data, res); - kfree(req); - - /* trigger next conversion (if any) on queue */ - pcap_adc_trigger(pcap); - - return IRQ_HANDLED; -} - -int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[], - void *callback, void *data) -{ - struct pcap_adc_request *req; - - /* This will be freed after we have a result */ - req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL); - if (!req) - return -ENOMEM; - - req->bank = bank; - req->flags = flags; - req->ch[0] = ch[0]; - req->ch[1] = ch[1]; - req->callback = callback; - req->data = data; - - mutex_lock(&pcap->adc_mutex); - if (pcap->adc_queue[pcap->adc_tail]) { - mutex_unlock(&pcap->adc_mutex); - kfree(req); - return -EBUSY; - } - pcap->adc_queue[pcap->adc_tail] = req; - pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1); - mutex_unlock(&pcap->adc_mutex); - - /* start conversion */ - pcap_adc_trigger(pcap); - - return 0; -} -EXPORT_SYMBOL_GPL(pcap_adc_async); - -static void pcap_adc_sync_cb(void *param, u16 res[]) -{ - struct pcap_adc_sync_request *req = param; - - req->res[0] = res[0]; - req->res[1] = res[1]; - complete(&req->completion); -} - -int pcap_adc_sync(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[], - u16 res[]) -{ - struct pcap_adc_sync_request sync_data; - int ret; - - init_completion(&sync_data.completion); - ret = pcap_adc_async(pcap, bank, flags, ch, pcap_adc_sync_cb, - &sync_data); - if (ret) - return ret; - wait_for_completion(&sync_data.completion); - res[0] = sync_data.res[0]; - res[1] = sync_data.res[1]; - - return 0; -} -EXPORT_SYMBOL_GPL(pcap_adc_sync); - -/* subdevs */ -static int pcap_remove_subdev(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - -static int __devinit pcap_add_subdev(struct pcap_chip *pcap, - struct pcap_subdev *subdev) -{ - struct platform_device *pdev; - int ret; - - pdev = platform_device_alloc(subdev->name, subdev->id); - if (!pdev) - return -ENOMEM; - - pdev->dev.parent = &pcap->spi->dev; - pdev->dev.platform_data = subdev->platform_data; - - ret = platform_device_add(pdev); - if (ret) - platform_device_put(pdev); - - return ret; -} - -static int __devexit ezx_pcap_remove(struct spi_device *spi) -{ - struct pcap_chip *pcap = dev_get_drvdata(&spi->dev); - struct pcap_platform_data *pdata = spi->dev.platform_data; - int i, adc_irq; - - /* remove all registered subdevs */ - device_for_each_child(&spi->dev, NULL, pcap_remove_subdev); - - /* cleanup ADC */ - adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? - PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE); - free_irq(adc_irq, pcap); - mutex_lock(&pcap->adc_mutex); - for (i = 0; i < PCAP_ADC_MAXQ; i++) - kfree(pcap->adc_queue[i]); - mutex_unlock(&pcap->adc_mutex); - - /* cleanup irqchip */ - for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) - irq_set_chip_and_handler(i, NULL, NULL); - - destroy_workqueue(pcap->workqueue); - - kfree(pcap); - - return 0; -} - -static int __devinit ezx_pcap_probe(struct spi_device *spi) -{ - struct pcap_platform_data *pdata = spi->dev.platform_data; - struct pcap_chip *pcap; - int i, adc_irq; - int ret = -ENODEV; - - /* platform data is required */ - if (!pdata) - goto ret; - - pcap = kzalloc(sizeof(*pcap), GFP_KERNEL); - if (!pcap) { - ret = -ENOMEM; - goto ret; - } - - mutex_init(&pcap->io_mutex); - mutex_init(&pcap->adc_mutex); - INIT_WORK(&pcap->isr_work, pcap_isr_work); - INIT_WORK(&pcap->msr_work, pcap_msr_work); - dev_set_drvdata(&spi->dev, pcap); - - /* setup spi */ - spi->bits_per_word = 32; - spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0); - ret = spi_setup(spi); - if (ret) - goto free_pcap; - - pcap->spi = spi; - - /* setup irq */ - pcap->irq_base = pdata->irq_base; - pcap->workqueue = create_singlethread_workqueue("pcapd"); - if (!pcap->workqueue) { - ret = -ENOMEM; - dev_err(&spi->dev, "can't create pcap thread\n"); - goto free_pcap; - } - - /* redirect interrupts to AP, except adcdone2 */ - if (!(pdata->config & PCAP_SECOND_PORT)) - ezx_pcap_write(pcap, PCAP_REG_INT_SEL, - (1 << PCAP_IRQ_ADCDONE2)); - - /* setup irq chip */ - for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { - irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); - irq_set_chip_data(i, pcap); -#ifdef CONFIG_ARM - set_irq_flags(i, IRQF_VALID); -#else - irq_set_noprobe(i); -#endif - } - - /* mask/ack all PCAP interrupts */ - ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT); - ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); - pcap->msr = PCAP_MASK_ALL_INTERRUPT; - - irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(spi->irq, pcap); - irq_set_chained_handler(spi->irq, pcap_irq_handler); - irq_set_irq_wake(spi->irq, 1); - - /* ADC */ - adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? - PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE); - - ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap); - if (ret) - goto free_irqchip; - - /* setup subdevs */ - for (i = 0; i < pdata->num_subdevs; i++) { - ret = pcap_add_subdev(pcap, &pdata->subdevs[i]); - if (ret) - goto remove_subdevs; - } - - /* board specific quirks */ - if (pdata->init) - pdata->init(pcap); - - return 0; - -remove_subdevs: - device_for_each_child(&spi->dev, NULL, pcap_remove_subdev); -/* free_adc: */ - free_irq(adc_irq, pcap); -free_irqchip: - for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) - irq_set_chip_and_handler(i, NULL, NULL); -/* destroy_workqueue: */ - destroy_workqueue(pcap->workqueue); -free_pcap: - kfree(pcap); -ret: - return ret; -} - -static struct spi_driver ezxpcap_driver = { - .probe = ezx_pcap_probe, - .remove = __devexit_p(ezx_pcap_remove), - .driver = { - .name = "ezx-pcap", - .owner = THIS_MODULE, - }, -}; - -static int __init ezx_pcap_init(void) -{ - return spi_register_driver(&ezxpcap_driver); -} - -static void __exit ezx_pcap_exit(void) -{ - spi_unregister_driver(&ezxpcap_driver); -} - -subsys_initcall(ezx_pcap_init); -module_exit(ezx_pcap_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Daniel Ribeiro / Harald Welte"); -MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver"); -MODULE_ALIAS("spi:ezx-pcap"); diff --git a/ANDROID_3.4.5/drivers/mfd/gmt/Kconfig b/ANDROID_3.4.5/drivers/mfd/gmt/Kconfig deleted file mode 100755 index 8fa734c6..00000000 --- a/ANDROID_3.4.5/drivers/mfd/gmt/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -config MFD_GMT - bool "GMT PMIC & Charger SUPPORT" - depends on I2C=y - select MFD_CORE - select REGMAP_I2C - select MFD_GMT_CORE -config MFD_GMT_CORE - bool diff --git a/ANDROID_3.4.5/drivers/mfd/gmt/Makefile b/ANDROID_3.4.5/drivers/mfd/gmt/Makefile deleted file mode 100755 index 7a10de77..00000000 --- a/ANDROID_3.4.5/drivers/mfd/gmt/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_MFD_GMT_CORE) += gmt-core.o diff --git a/ANDROID_3.4.5/drivers/mfd/gmt/gmt-core.c b/ANDROID_3.4.5/drivers/mfd/gmt/gmt-core.c deleted file mode 100755 index c50987fc..00000000 --- a/ANDROID_3.4.5/drivers/mfd/gmt/gmt-core.c +++ /dev/null @@ -1,285 +0,0 @@ -/*++ - drivers/mtd/gmt/gmt-core.c - GMT Core driver - - Copyright (c) 2013 WonderMedia Technologies, Inc. - - This program is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software Foundation, - either version 2 of the License, or (at your option) any later version. - - 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, see <http://www.gnu.org/licenses/>. - - WonderMedia Technologies, Inc. - 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. ---*/ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/pm_runtime.h> -#include <linux/mutex.h> -#include <linux/mfd/core.h> -#include <mach/gmt-core.h> -#include <linux/regmap.h> - -static struct mfd_cell gmt_devs[] = { - { - .name = "gmt-pmic", - }, { - .name = "gmt-charger", - }, -}; - -int gmt2214_reg_read(struct gmt2214_dev *gmt2214, u8 reg, void *dest) -{ - struct i2c_msg msg[2]; - unsigned char data[4]; - int err; - struct i2c_client *client; - - client = gmt2214->i2c; - - if (!client || !client->adapter) - return -ENODEV; - - if (!dest) - return -EINVAL; - - data[0] = reg; - msg[0].addr = client->addr; - msg[0].flags = 0 | I2C_M_NOSTART; - msg[0].len = 1; - msg[0].buf = (unsigned char *)data; - - msg[1].addr = client->addr; - msg[1].flags = (I2C_M_RD); - msg[1].len = 1; - msg[1].buf = (unsigned char *)dest; - - err = i2c_transfer(client->adapter, msg, sizeof(msg)/sizeof(struct i2c_msg)); - return err; -} -EXPORT_SYMBOL_GPL(gmt2214_reg_read); - -int gmt2214_reg_write(struct gmt2214_dev *gmt2214, u8 reg, u8 value) -{ - unsigned char buffer4Write[256]; - struct i2c_client *client = gmt2214->i2c; - struct i2c_msg msgs[1] = { - { - .addr = client->addr, - .flags = 0, - .len = 2, - .buf = buffer4Write - } - }; - - buffer4Write[0] = reg; - buffer4Write[1] = value; - - return i2c_transfer(client->adapter, msgs, 1); - -} -EXPORT_SYMBOL_GPL(gmt2214_reg_write); - -static struct regmap_config gmt2214_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -}; - -static int gmt2214_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct gmt2214_platform_data *pdata = i2c->dev.platform_data; - struct gmt2214_dev *gmt2214; - int ret; - - gmt2214 = devm_kzalloc(&i2c->dev, sizeof(struct gmt2214_dev), - GFP_KERNEL); - if (gmt2214 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, gmt2214); - gmt2214->dev = &i2c->dev; - gmt2214->i2c = i2c; - - if (pdata) - gmt2214->device_type = pdata->device_type; - - gmt2214->regmap = regmap_init_i2c(i2c, &gmt2214_regmap_config); - if (IS_ERR(gmt2214->regmap)) { - ret = PTR_ERR(gmt2214->regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); - goto err; - } - - pm_runtime_set_active(gmt2214->dev); - - ret = mfd_add_devices(gmt2214->dev, -1, gmt_devs, - ARRAY_SIZE(gmt_devs), NULL, 0); - - if (ret < 0) - goto err; - - return ret; - -err: - mfd_remove_devices(gmt2214->dev); - regmap_exit(gmt2214->regmap); - return ret; -} - -static int gmt2214_i2c_remove(struct i2c_client *i2c) -{ - struct gmt2214_dev *gmt2214 = i2c_get_clientdata(i2c); - - mfd_remove_devices(gmt2214->dev); - regmap_exit(gmt2214->regmap); - return 0; -} - -static struct i2c_board_info gmt_i2c_board_info = { - .type = "gmt2214", - .flags = 0x00, - .addr = 0x12, - .platform_data = NULL, - .archdata = NULL, - .irq = -1, -}; - -static const struct i2c_device_id gmt2214_i2c_id[] = { - {"gmt2214", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, gmt2214_i2c_id); - -static struct i2c_driver gmt2214_i2c_driver = { - .driver = { - .name = "gmt2214", - .owner = THIS_MODULE, - }, - .probe = gmt2214_i2c_probe, - .remove = gmt2214_i2c_remove, - .id_table = gmt2214_i2c_id, -}; - -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - -#define par_len 80 -static unsigned int g_i2cbus_id = 3; -static unsigned int g_pmic_en = 0; - -static int parse_pmic_param(void) -{ - int retval; - unsigned char buf[par_len]; - unsigned char tmp_buf[par_len]; - unsigned int delay_time; - int i = 0; - int j = 0; - int varlen = par_len; - char *varname = "wmt.pmic.param"; - unsigned int pmic_en = 0; - retval = wmt_getsyspara(varname, buf, &varlen); - if (retval == 0) { - pmic_en = (buf[i] - '0' == 1)?1:0; - if (pmic_en == 0) {/*disable*/ - g_pmic_en = 0; - return -1; - } - i += 2; - for (; i < par_len; ++i) { - if (buf[i] == ':') - break; - tmp_buf[j] = buf[i]; - ++j; - } - if (strncmp(tmp_buf,"gmt2214",7)) { - g_pmic_en = 0; - return -1; - } - ++i; - - sscanf((buf + i), "%d:%d", &g_i2cbus_id, &delay_time); - } else { - g_pmic_en = 0; - return -1; - } - g_pmic_en = 1; - return 0; -} - -static unsigned int g_chg_en = 0; -int parse_charger_param(void) -{ - int retval; - unsigned char buf[240]; - int varlen = par_len; - //char *varname = "wmt.io.chg"; - char *varname = "wmt.charger.param"; - retval = wmt_getsyspara(varname, buf, &varlen); - if (retval == 0) { - g_chg_en = (buf[0] - '0' == 1)?1:0; - if (g_chg_en == 0) - return -1; - if (strncmp((buf + 2), "g2214", 5)) { - g_chg_en = 0; - return -1; - } - } else { - g_chg_en = 0; - return -1; - } - g_chg_en = 1; - return 1; -} -static int __init gmt2214_i2c_init(void) -{ - struct i2c_board_info *gmt2214_i2c_bi; - struct i2c_adapter *adapter = NULL; - struct i2c_client *client = NULL; - - parse_pmic_param(); - parse_charger_param(); - if (g_pmic_en == 0 && g_chg_en == 0) { - printk("Don't support GMT2214\n"); - return -ENODEV; - } - gmt2214_i2c_bi = &gmt_i2c_board_info; - adapter = i2c_get_adapter(g_i2cbus_id);/*in bus 3*/ - - if (NULL == adapter) { - printk("can not get i2c adapter, client address error\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, gmt2214_i2c_bi); - if (client == NULL) { - printk("allocate i2c client failed\n"); - return -ENODEV; - } - i2c_put_adapter(adapter); - - return i2c_add_driver(&gmt2214_i2c_driver); -} - -subsys_initcall_sync(gmt2214_i2c_init); - -static void __exit gmt2214_i2c_exit(void) -{ - i2c_del_driver(&gmt2214_i2c_driver); -} -module_exit(gmt2214_i2c_exit); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("GMT2214 Core Driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/htc-egpio.c b/ANDROID_3.4.5/drivers/mfd/htc-egpio.c deleted file mode 100644 index bbaec0cc..00000000 --- a/ANDROID_3.4.5/drivers/mfd/htc-egpio.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Support for the GPIO/IRQ expander chips present on several HTC phones. - * These are implemented in CPLD chips present on the board. - * - * Copyright (c) 2007 Kevin O'Connor <kevin@koconnor.net> - * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com> - * - * This file may be distributed under the terms of the GNU GPL license. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/spinlock.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/mfd/htc-egpio.h> - -struct egpio_chip { - int reg_start; - int cached_values; - unsigned long is_out; - struct device *dev; - struct gpio_chip chip; -}; - -struct egpio_info { - spinlock_t lock; - - /* iomem info */ - void __iomem *base_addr; - int bus_shift; /* byte shift */ - int reg_shift; /* bit shift */ - int reg_mask; - - /* irq info */ - int ack_register; - int ack_write; - u16 irqs_enabled; - uint irq_start; - int nirqs; - uint chained_irq; - - /* egpio info */ - struct egpio_chip *chip; - int nchips; -}; - -static inline void egpio_writew(u16 value, struct egpio_info *ei, int reg) -{ - writew(value, ei->base_addr + (reg << ei->bus_shift)); -} - -static inline u16 egpio_readw(struct egpio_info *ei, int reg) -{ - return readw(ei->base_addr + (reg << ei->bus_shift)); -} - -/* - * IRQs - */ - -static inline void ack_irqs(struct egpio_info *ei) -{ - egpio_writew(ei->ack_write, ei, ei->ack_register); - pr_debug("EGPIO ack - write %x to base+%x\n", - ei->ack_write, ei->ack_register << ei->bus_shift); -} - -static void egpio_ack(struct irq_data *data) -{ -} - -/* There does not appear to be a way to proactively mask interrupts - * on the egpio chip itself. So, we simply ignore interrupts that - * aren't desired. */ -static void egpio_mask(struct irq_data *data) -{ - struct egpio_info *ei = irq_data_get_irq_chip_data(data); - ei->irqs_enabled &= ~(1 << (data->irq - ei->irq_start)); - pr_debug("EGPIO mask %d %04x\n", data->irq, ei->irqs_enabled); -} - -static void egpio_unmask(struct irq_data *data) -{ - struct egpio_info *ei = irq_data_get_irq_chip_data(data); - ei->irqs_enabled |= 1 << (data->irq - ei->irq_start); - pr_debug("EGPIO unmask %d %04x\n", data->irq, ei->irqs_enabled); -} - -static struct irq_chip egpio_muxed_chip = { - .name = "htc-egpio", - .irq_ack = egpio_ack, - .irq_mask = egpio_mask, - .irq_unmask = egpio_unmask, -}; - -static void egpio_handler(unsigned int irq, struct irq_desc *desc) -{ - struct egpio_info *ei = irq_desc_get_handler_data(desc); - int irqpin; - - /* Read current pins. */ - unsigned long readval = egpio_readw(ei, ei->ack_register); - pr_debug("IRQ reg: %x\n", (unsigned int)readval); - /* Ack/unmask interrupts. */ - ack_irqs(ei); - /* Process all set pins. */ - readval &= ei->irqs_enabled; - for_each_set_bit(irqpin, &readval, ei->nirqs) { - /* Run irq handler */ - pr_debug("got IRQ %d\n", irqpin); - generic_handle_irq(ei->irq_start + irqpin); - } -} - -int htc_egpio_get_wakeup_irq(struct device *dev) -{ - struct egpio_info *ei = dev_get_drvdata(dev); - - /* Read current pins. */ - u16 readval = egpio_readw(ei, ei->ack_register); - /* Ack/unmask interrupts. */ - ack_irqs(ei); - /* Return first set pin. */ - readval &= ei->irqs_enabled; - return ei->irq_start + ffs(readval) - 1; -} -EXPORT_SYMBOL(htc_egpio_get_wakeup_irq); - -static inline int egpio_pos(struct egpio_info *ei, int bit) -{ - return bit >> ei->reg_shift; -} - -static inline int egpio_bit(struct egpio_info *ei, int bit) -{ - return 1 << (bit & ((1 << ei->reg_shift)-1)); -} - -/* - * Input pins - */ - -static int egpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct egpio_chip *egpio; - struct egpio_info *ei; - unsigned bit; - int reg; - int value; - - pr_debug("egpio_get_value(%d)\n", chip->base + offset); - - egpio = container_of(chip, struct egpio_chip, chip); - ei = dev_get_drvdata(egpio->dev); - bit = egpio_bit(ei, offset); - reg = egpio->reg_start + egpio_pos(ei, offset); - - value = egpio_readw(ei, reg); - pr_debug("readw(%p + %x) = %x\n", - ei->base_addr, reg << ei->bus_shift, value); - return value & bit; -} - -static int egpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct egpio_chip *egpio; - - egpio = container_of(chip, struct egpio_chip, chip); - return test_bit(offset, &egpio->is_out) ? -EINVAL : 0; -} - - -/* - * Output pins - */ - -static void egpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - unsigned long flag; - struct egpio_chip *egpio; - struct egpio_info *ei; - unsigned bit; - int pos; - int reg; - int shift; - - pr_debug("egpio_set(%s, %d(%d), %d)\n", - chip->label, offset, offset+chip->base, value); - - egpio = container_of(chip, struct egpio_chip, chip); - ei = dev_get_drvdata(egpio->dev); - bit = egpio_bit(ei, offset); - pos = egpio_pos(ei, offset); - reg = egpio->reg_start + pos; - shift = pos << ei->reg_shift; - - pr_debug("egpio %s: reg %d = 0x%04x\n", value ? "set" : "clear", - reg, (egpio->cached_values >> shift) & ei->reg_mask); - - spin_lock_irqsave(&ei->lock, flag); - if (value) - egpio->cached_values |= (1 << offset); - else - egpio->cached_values &= ~(1 << offset); - egpio_writew((egpio->cached_values >> shift) & ei->reg_mask, ei, reg); - spin_unlock_irqrestore(&ei->lock, flag); -} - -static int egpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct egpio_chip *egpio; - - egpio = container_of(chip, struct egpio_chip, chip); - if (test_bit(offset, &egpio->is_out)) { - egpio_set(chip, offset, value); - return 0; - } else { - return -EINVAL; - } -} - -static void egpio_write_cache(struct egpio_info *ei) -{ - int i; - struct egpio_chip *egpio; - int shift; - - for (i = 0; i < ei->nchips; i++) { - egpio = &(ei->chip[i]); - if (!egpio->is_out) - continue; - - for (shift = 0; shift < egpio->chip.ngpio; - shift += (1<<ei->reg_shift)) { - - int reg = egpio->reg_start + egpio_pos(ei, shift); - - if (!((egpio->is_out >> shift) & ei->reg_mask)) - continue; - - pr_debug("EGPIO: setting %x to %x, was %x\n", reg, - (egpio->cached_values >> shift) & ei->reg_mask, - egpio_readw(ei, reg)); - - egpio_writew((egpio->cached_values >> shift) - & ei->reg_mask, ei, reg); - } - } -} - - -/* - * Setup - */ - -static int __init egpio_probe(struct platform_device *pdev) -{ - struct htc_egpio_platform_data *pdata = pdev->dev.platform_data; - struct resource *res; - struct egpio_info *ei; - struct gpio_chip *chip; - unsigned int irq, irq_end; - int i; - int ret; - - /* Initialize ei data structure. */ - ei = kzalloc(sizeof(*ei), GFP_KERNEL); - if (!ei) - return -ENOMEM; - - spin_lock_init(&ei->lock); - - /* Find chained irq */ - ret = -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) - ei->chained_irq = res->start; - - /* Map egpio chip into virtual address space. */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - goto fail; - ei->base_addr = ioremap_nocache(res->start, resource_size(res)); - if (!ei->base_addr) - goto fail; - pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); - - if ((pdata->bus_width != 16) && (pdata->bus_width != 32)) - goto fail; - ei->bus_shift = fls(pdata->bus_width - 1) - 3; - pr_debug("bus_shift = %d\n", ei->bus_shift); - - if ((pdata->reg_width != 8) && (pdata->reg_width != 16)) - goto fail; - ei->reg_shift = fls(pdata->reg_width - 1); - pr_debug("reg_shift = %d\n", ei->reg_shift); - - ei->reg_mask = (1 << pdata->reg_width) - 1; - - platform_set_drvdata(pdev, ei); - - ei->nchips = pdata->num_chips; - ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL); - if (!ei->chip) { - ret = -ENOMEM; - goto fail; - } - for (i = 0; i < ei->nchips; i++) { - ei->chip[i].reg_start = pdata->chip[i].reg_start; - ei->chip[i].cached_values = pdata->chip[i].initial_values; - ei->chip[i].is_out = pdata->chip[i].direction; - ei->chip[i].dev = &(pdev->dev); - chip = &(ei->chip[i].chip); - chip->label = "htc-egpio"; - chip->dev = &pdev->dev; - chip->owner = THIS_MODULE; - chip->get = egpio_get; - chip->set = egpio_set; - chip->direction_input = egpio_direction_input; - chip->direction_output = egpio_direction_output; - chip->base = pdata->chip[i].gpio_base; - chip->ngpio = pdata->chip[i].num_gpios; - - gpiochip_add(chip); - } - - /* Set initial pin values */ - egpio_write_cache(ei); - - ei->irq_start = pdata->irq_base; - ei->nirqs = pdata->num_irqs; - ei->ack_register = pdata->ack_register; - - if (ei->chained_irq) { - /* Setup irq handlers */ - ei->ack_write = 0xFFFF; - if (pdata->invert_acks) - ei->ack_write = 0; - irq_end = ei->irq_start + ei->nirqs; - for (irq = ei->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, &egpio_muxed_chip, - handle_simple_irq); - irq_set_chip_data(irq, ei); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - irq_set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(ei->chained_irq, ei); - irq_set_chained_handler(ei->chained_irq, egpio_handler); - ack_irqs(ei); - - device_init_wakeup(&pdev->dev, 1); - } - - return 0; - -fail: - printk(KERN_ERR "EGPIO failed to setup\n"); - kfree(ei); - return ret; -} - -static int __exit egpio_remove(struct platform_device *pdev) -{ - struct egpio_info *ei = platform_get_drvdata(pdev); - unsigned int irq, irq_end; - - if (ei->chained_irq) { - irq_end = ei->irq_start + ei->nirqs; - for (irq = ei->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, NULL, NULL); - set_irq_flags(irq, 0); - } - irq_set_chained_handler(ei->chained_irq, NULL); - device_init_wakeup(&pdev->dev, 0); - } - iounmap(ei->base_addr); - kfree(ei->chip); - kfree(ei); - - return 0; -} - -#ifdef CONFIG_PM -static int egpio_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct egpio_info *ei = platform_get_drvdata(pdev); - - if (ei->chained_irq && device_may_wakeup(&pdev->dev)) - enable_irq_wake(ei->chained_irq); - return 0; -} - -static int egpio_resume(struct platform_device *pdev) -{ - struct egpio_info *ei = platform_get_drvdata(pdev); - - if (ei->chained_irq && device_may_wakeup(&pdev->dev)) - disable_irq_wake(ei->chained_irq); - - /* Update registers from the cache, in case - the CPLD was powered off during suspend */ - egpio_write_cache(ei); - return 0; -} -#else -#define egpio_suspend NULL -#define egpio_resume NULL -#endif - - -static struct platform_driver egpio_driver = { - .driver = { - .name = "htc-egpio", - }, - .remove = __exit_p(egpio_remove), - .suspend = egpio_suspend, - .resume = egpio_resume, -}; - -static int __init egpio_init(void) -{ - return platform_driver_probe(&egpio_driver, egpio_probe); -} - -static void __exit egpio_exit(void) -{ - platform_driver_unregister(&egpio_driver); -} - -/* start early for dependencies */ -subsys_initcall(egpio_init); -module_exit(egpio_exit) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kevin O'Connor <kevin@koconnor.net>"); diff --git a/ANDROID_3.4.5/drivers/mfd/htc-i2cpld.c b/ANDROID_3.4.5/drivers/mfd/htc-i2cpld.c deleted file mode 100644 index d55065cc..00000000 --- a/ANDROID_3.4.5/drivers/mfd/htc-i2cpld.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * htc-i2cpld.c - * Chip driver for an unknown CPLD chip found on omap850 HTC devices like - * the HTC Wizard and HTC Herald. - * The cpld is located on the i2c bus and acts as an input/output GPIO - * extender. - * - * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com> - * - * Based on work done in the linwizard project - * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/spinlock.h> -#include <linux/htcpld.h> -#include <linux/gpio.h> -#include <linux/slab.h> - -struct htcpld_chip { - spinlock_t lock; - - /* chip info */ - u8 reset; - u8 addr; - struct device *dev; - struct i2c_client *client; - - /* Output details */ - u8 cache_out; - struct gpio_chip chip_out; - - /* Input details */ - u8 cache_in; - struct gpio_chip chip_in; - - u16 irqs_enabled; - uint irq_start; - int nirqs; - - unsigned int flow_type; - /* - * Work structure to allow for setting values outside of any - * possible interrupt context - */ - struct work_struct set_val_work; -}; - -struct htcpld_data { - /* irq info */ - u16 irqs_enabled; - uint irq_start; - int nirqs; - uint chained_irq; - unsigned int int_reset_gpio_hi; - unsigned int int_reset_gpio_lo; - - /* htcpld info */ - struct htcpld_chip *chip; - unsigned int nchips; -}; - -/* There does not appear to be a way to proactively mask interrupts - * on the htcpld chip itself. So, we simply ignore interrupts that - * aren't desired. */ -static void htcpld_mask(struct irq_data *data) -{ - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); - chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start)); - pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled); -} -static void htcpld_unmask(struct irq_data *data) -{ - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); - chip->irqs_enabled |= 1 << (data->irq - chip->irq_start); - pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled); -} - -static int htcpld_set_type(struct irq_data *data, unsigned int flags) -{ - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); - - if (flags & ~IRQ_TYPE_SENSE_MASK) - return -EINVAL; - - /* We only allow edge triggering */ - if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) - return -EINVAL; - - chip->flow_type = flags; - return 0; -} - -static struct irq_chip htcpld_muxed_chip = { - .name = "htcpld", - .irq_mask = htcpld_mask, - .irq_unmask = htcpld_unmask, - .irq_set_type = htcpld_set_type, -}; - -/* To properly dispatch IRQ events, we need to read from the - * chip. This is an I2C action that could possibly sleep - * (which is bad in interrupt context) -- so we use a threaded - * interrupt handler to get around that. - */ -static irqreturn_t htcpld_handler(int irq, void *dev) -{ - struct htcpld_data *htcpld = dev; - unsigned int i; - unsigned long flags; - int irqpin; - - if (!htcpld) { - pr_debug("htcpld is null in ISR\n"); - return IRQ_HANDLED; - } - - /* - * For each chip, do a read of the chip and trigger any interrupts - * desired. The interrupts will be triggered from LSB to MSB (i.e. - * bit 0 first, then bit 1, etc.) - * - * For chips that have no interrupt range specified, just skip 'em. - */ - for (i = 0; i < htcpld->nchips; i++) { - struct htcpld_chip *chip = &htcpld->chip[i]; - struct i2c_client *client; - int val; - unsigned long uval, old_val; - - if (!chip) { - pr_debug("chip %d is null in ISR\n", i); - continue; - } - - if (chip->nirqs == 0) - continue; - - client = chip->client; - if (!client) { - pr_debug("client %d is null in ISR\n", i); - continue; - } - - /* Scan the chip */ - val = i2c_smbus_read_byte_data(client, chip->cache_out); - if (val < 0) { - /* Throw a warning and skip this chip */ - dev_warn(chip->dev, "Unable to read from chip: %d\n", - val); - continue; - } - - uval = (unsigned long)val; - - spin_lock_irqsave(&chip->lock, flags); - - /* Save away the old value so we can compare it */ - old_val = chip->cache_in; - - /* Write the new value */ - chip->cache_in = uval; - - spin_unlock_irqrestore(&chip->lock, flags); - - /* - * For each bit in the data (starting at bit 0), trigger - * associated interrupts. - */ - for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { - unsigned oldb, newb, type = chip->flow_type; - - irq = chip->irq_start + irqpin; - - /* Run the IRQ handler, but only if the bit value - * changed, and the proper flags are set */ - oldb = (old_val >> irqpin) & 1; - newb = (uval >> irqpin) & 1; - - if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) || - (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) { - pr_debug("fire IRQ %d\n", irqpin); - generic_handle_irq(irq); - } - } - } - - /* - * In order to continue receiving interrupts, the int_reset_gpio must - * be asserted. - */ - if (htcpld->int_reset_gpio_hi) - gpio_set_value(htcpld->int_reset_gpio_hi, 1); - if (htcpld->int_reset_gpio_lo) - gpio_set_value(htcpld->int_reset_gpio_lo, 0); - - return IRQ_HANDLED; -} - -/* - * The GPIO set routines can be called from interrupt context, especially if, - * for example they're attached to the led-gpio framework and a trigger is - * enabled. As such, we declared work above in the htcpld_chip structure, - * and that work is scheduled in the set routine. The kernel can then run - * the I2C functions, which will sleep, in process context. - */ -static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) -{ - struct i2c_client *client; - struct htcpld_chip *chip_data; - unsigned long flags; - - chip_data = container_of(chip, struct htcpld_chip, chip_out); - if (!chip_data) - return; - - client = chip_data->client; - if (client == NULL) - return; - - spin_lock_irqsave(&chip_data->lock, flags); - if (val) - chip_data->cache_out |= (1 << offset); - else - chip_data->cache_out &= ~(1 << offset); - spin_unlock_irqrestore(&chip_data->lock, flags); - - schedule_work(&(chip_data->set_val_work)); -} - -static void htcpld_chip_set_ni(struct work_struct *work) -{ - struct htcpld_chip *chip_data; - struct i2c_client *client; - - chip_data = container_of(work, struct htcpld_chip, set_val_work); - client = chip_data->client; - i2c_smbus_read_byte_data(client, chip_data->cache_out); -} - -static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) -{ - struct htcpld_chip *chip_data; - int val = 0; - int is_input = 0; - - /* Try out first */ - chip_data = container_of(chip, struct htcpld_chip, chip_out); - if (!chip_data) { - /* Try in */ - is_input = 1; - chip_data = container_of(chip, struct htcpld_chip, chip_in); - if (!chip_data) - return -EINVAL; - } - - /* Determine if this is an input or output GPIO */ - if (!is_input) - /* Use the output cache */ - val = (chip_data->cache_out >> offset) & 1; - else - /* Use the input cache */ - val = (chip_data->cache_in >> offset) & 1; - - if (val) - return 1; - else - return 0; -} - -static int htcpld_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - htcpld_chip_set(chip, offset, value); - return 0; -} - -static int htcpld_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - /* - * No-op: this function can only be called on the input chip. - * We do however make sure the offset is within range. - */ - return (offset < chip->ngpio) ? 0 : -EINVAL; -} - -static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct htcpld_chip *chip_data; - - chip_data = container_of(chip, struct htcpld_chip, chip_in); - - if (offset < chip_data->nirqs) - return chip_data->irq_start + offset; - else - return -EINVAL; -} - -static void htcpld_chip_reset(struct i2c_client *client) -{ - struct htcpld_chip *chip_data = i2c_get_clientdata(client); - if (!chip_data) - return; - - i2c_smbus_read_byte_data( - client, (chip_data->cache_out = chip_data->reset)); -} - -static int __devinit htcpld_setup_chip_irq( - struct platform_device *pdev, - int chip_index) -{ - struct htcpld_data *htcpld; - struct device *dev = &pdev->dev; - struct htcpld_core_platform_data *pdata; - struct htcpld_chip *chip; - struct htcpld_chip_platform_data *plat_chip_data; - unsigned int irq, irq_end; - int ret = 0; - - /* Get the platform and driver data */ - pdata = dev->platform_data; - htcpld = platform_get_drvdata(pdev); - chip = &htcpld->chip[chip_index]; - plat_chip_data = &pdata->chip[chip_index]; - - /* Setup irq handlers */ - irq_end = chip->irq_start + chip->nirqs; - for (irq = chip->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, &htcpld_muxed_chip, - handle_simple_irq); - irq_set_chip_data(irq, chip); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -#else - irq_set_probe(irq); -#endif - } - - return ret; -} - -static int __devinit htcpld_register_chip_i2c( - struct platform_device *pdev, - int chip_index) -{ - struct htcpld_data *htcpld; - struct device *dev = &pdev->dev; - struct htcpld_core_platform_data *pdata; - struct htcpld_chip *chip; - struct htcpld_chip_platform_data *plat_chip_data; - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info; - - /* Get the platform and driver data */ - pdata = dev->platform_data; - htcpld = platform_get_drvdata(pdev); - chip = &htcpld->chip[chip_index]; - plat_chip_data = &pdata->chip[chip_index]; - - adapter = i2c_get_adapter(pdata->i2c_adapter_id); - if (adapter == NULL) { - /* Eek, no such I2C adapter! Bail out. */ - dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n", - plat_chip_data->addr, pdata->i2c_adapter_id); - return -ENODEV; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { - dev_warn(dev, "i2c adapter %d non-functional\n", - pdata->i2c_adapter_id); - return -EINVAL; - } - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = plat_chip_data->addr; - strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE); - info.platform_data = chip; - - /* Add the I2C device. This calls the probe() function. */ - client = i2c_new_device(adapter, &info); - if (!client) { - /* I2C device registration failed, contineu with the next */ - dev_warn(dev, "Unable to add I2C device for 0x%x\n", - plat_chip_data->addr); - return -ENODEV; - } - - i2c_set_clientdata(client, chip); - snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr); - chip->client = client; - - /* Reset the chip */ - htcpld_chip_reset(client); - chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out); - - return 0; -} - -static void __devinit htcpld_unregister_chip_i2c( - struct platform_device *pdev, - int chip_index) -{ - struct htcpld_data *htcpld; - struct htcpld_chip *chip; - - /* Get the platform and driver data */ - htcpld = platform_get_drvdata(pdev); - chip = &htcpld->chip[chip_index]; - - if (chip->client) - i2c_unregister_device(chip->client); -} - -static int __devinit htcpld_register_chip_gpio( - struct platform_device *pdev, - int chip_index) -{ - struct htcpld_data *htcpld; - struct device *dev = &pdev->dev; - struct htcpld_core_platform_data *pdata; - struct htcpld_chip *chip; - struct htcpld_chip_platform_data *plat_chip_data; - struct gpio_chip *gpio_chip; - int ret = 0; - - /* Get the platform and driver data */ - pdata = dev->platform_data; - htcpld = platform_get_drvdata(pdev); - chip = &htcpld->chip[chip_index]; - plat_chip_data = &pdata->chip[chip_index]; - - /* Setup the GPIO chips */ - gpio_chip = &(chip->chip_out); - gpio_chip->label = "htcpld-out"; - gpio_chip->dev = dev; - gpio_chip->owner = THIS_MODULE; - gpio_chip->get = htcpld_chip_get; - gpio_chip->set = htcpld_chip_set; - gpio_chip->direction_input = NULL; - gpio_chip->direction_output = htcpld_direction_output; - gpio_chip->base = plat_chip_data->gpio_out_base; - gpio_chip->ngpio = plat_chip_data->num_gpios; - - gpio_chip = &(chip->chip_in); - gpio_chip->label = "htcpld-in"; - gpio_chip->dev = dev; - gpio_chip->owner = THIS_MODULE; - gpio_chip->get = htcpld_chip_get; - gpio_chip->set = NULL; - gpio_chip->direction_input = htcpld_direction_input; - gpio_chip->direction_output = NULL; - gpio_chip->to_irq = htcpld_chip_to_irq; - gpio_chip->base = plat_chip_data->gpio_in_base; - gpio_chip->ngpio = plat_chip_data->num_gpios; - - /* Add the GPIO chips */ - ret = gpiochip_add(&(chip->chip_out)); - if (ret) { - dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n", - plat_chip_data->addr, ret); - return ret; - } - - ret = gpiochip_add(&(chip->chip_in)); - if (ret) { - int error; - - dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n", - plat_chip_data->addr, ret); - - error = gpiochip_remove(&(chip->chip_out)); - if (error) - dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error); - - return ret; - } - - return 0; -} - -static int __devinit htcpld_setup_chips(struct platform_device *pdev) -{ - struct htcpld_data *htcpld; - struct device *dev = &pdev->dev; - struct htcpld_core_platform_data *pdata; - int i; - - /* Get the platform and driver data */ - pdata = dev->platform_data; - htcpld = platform_get_drvdata(pdev); - - /* Setup each chip's output GPIOs */ - htcpld->nchips = pdata->num_chip; - htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips, - GFP_KERNEL); - if (!htcpld->chip) { - dev_warn(dev, "Unable to allocate memory for chips\n"); - return -ENOMEM; - } - - /* Add the chips as best we can */ - for (i = 0; i < htcpld->nchips; i++) { - int ret; - - /* Setup the HTCPLD chips */ - htcpld->chip[i].reset = pdata->chip[i].reset; - htcpld->chip[i].cache_out = pdata->chip[i].reset; - htcpld->chip[i].cache_in = 0; - htcpld->chip[i].dev = dev; - htcpld->chip[i].irq_start = pdata->chip[i].irq_base; - htcpld->chip[i].nirqs = pdata->chip[i].num_irqs; - - INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni); - spin_lock_init(&(htcpld->chip[i].lock)); - - /* Setup the interrupts for the chip */ - if (htcpld->chained_irq) { - ret = htcpld_setup_chip_irq(pdev, i); - if (ret) - continue; - } - - /* Register the chip with I2C */ - ret = htcpld_register_chip_i2c(pdev, i); - if (ret) - continue; - - - /* Register the chips with the GPIO subsystem */ - ret = htcpld_register_chip_gpio(pdev, i); - if (ret) { - /* Unregister the chip from i2c and continue */ - htcpld_unregister_chip_i2c(pdev, i); - continue; - } - - dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr); - } - - return 0; -} - -static int __devinit htcpld_core_probe(struct platform_device *pdev) -{ - struct htcpld_data *htcpld; - struct device *dev = &pdev->dev; - struct htcpld_core_platform_data *pdata; - struct resource *res; - int ret = 0; - - if (!dev) - return -ENODEV; - - pdata = dev->platform_data; - if (!pdata) { - dev_warn(dev, "Platform data not found for htcpld core!\n"); - return -ENXIO; - } - - htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL); - if (!htcpld) - return -ENOMEM; - - /* Find chained irq */ - ret = -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) { - int flags; - htcpld->chained_irq = res->start; - - /* Setup the chained interrupt handler */ - flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; - ret = request_threaded_irq(htcpld->chained_irq, - NULL, htcpld_handler, - flags, pdev->name, htcpld); - if (ret) { - dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret); - goto fail; - } else - device_init_wakeup(dev, 0); - } - - /* Set the driver data */ - platform_set_drvdata(pdev, htcpld); - - /* Setup the htcpld chips */ - ret = htcpld_setup_chips(pdev); - if (ret) - goto fail; - - /* Request the GPIO(s) for the int reset and set them up */ - if (pdata->int_reset_gpio_hi) { - ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core"); - if (ret) { - /* - * If it failed, that sucks, but we can probably - * continue on without it. - */ - dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n"); - htcpld->int_reset_gpio_hi = 0; - } else { - htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi; - gpio_set_value(htcpld->int_reset_gpio_hi, 1); - } - } - - if (pdata->int_reset_gpio_lo) { - ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core"); - if (ret) { - /* - * If it failed, that sucks, but we can probably - * continue on without it. - */ - dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n"); - htcpld->int_reset_gpio_lo = 0; - } else { - htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo; - gpio_set_value(htcpld->int_reset_gpio_lo, 0); - } - } - - dev_info(dev, "Initialized successfully\n"); - return 0; - -fail: - kfree(htcpld); - return ret; -} - -/* The I2C Driver -- used internally */ -static const struct i2c_device_id htcpld_chip_id[] = { - { "htcpld-chip", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, htcpld_chip_id); - - -static struct i2c_driver htcpld_chip_driver = { - .driver = { - .name = "htcpld-chip", - }, - .id_table = htcpld_chip_id, -}; - -/* The Core Driver */ -static struct platform_driver htcpld_core_driver = { - .driver = { - .name = "i2c-htcpld", - }, -}; - -static int __init htcpld_core_init(void) -{ - int ret; - - /* Register the I2C Chip driver */ - ret = i2c_add_driver(&htcpld_chip_driver); - if (ret) - return ret; - - /* Probe for our chips */ - return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); -} - -static void __exit htcpld_core_exit(void) -{ - i2c_del_driver(&htcpld_chip_driver); - platform_driver_unregister(&htcpld_core_driver); -} - -module_init(htcpld_core_init); -module_exit(htcpld_core_exit); - -MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>"); -MODULE_DESCRIPTION("I2C HTC PLD Driver"); -MODULE_LICENSE("GPL"); - diff --git a/ANDROID_3.4.5/drivers/mfd/htc-pasic3.c b/ANDROID_3.4.5/drivers/mfd/htc-pasic3.c deleted file mode 100644 index 04c7093d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/htc-pasic3.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Core driver for HTC PASIC3 LED/DS1WM chip. - * - * Copyright (C) 2006 Philipp Zabel <philipp.zabel@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <linux/gpio.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/mfd/core.h> -#include <linux/mfd/ds1wm.h> -#include <linux/mfd/htc-pasic3.h> -#include <linux/slab.h> - -struct pasic3_data { - void __iomem *mapping; - unsigned int bus_shift; -}; - -#define REG_ADDR 5 -#define REG_DATA 6 - -#define READ_MODE 0x80 - -/* - * write to a secondary register on the PASIC3 - */ -void pasic3_write_register(struct device *dev, u32 reg, u8 val) -{ - struct pasic3_data *asic = dev_get_drvdata(dev); - int bus_shift = asic->bus_shift; - void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift); - void __iomem *data = asic->mapping + (REG_DATA << bus_shift); - - __raw_writeb(~READ_MODE & reg, addr); - __raw_writeb(val, data); -} -EXPORT_SYMBOL(pasic3_write_register); /* for leds-pasic3 */ - -/* - * read from a secondary register on the PASIC3 - */ -u8 pasic3_read_register(struct device *dev, u32 reg) -{ - struct pasic3_data *asic = dev_get_drvdata(dev); - int bus_shift = asic->bus_shift; - void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift); - void __iomem *data = asic->mapping + (REG_DATA << bus_shift); - - __raw_writeb(READ_MODE | reg, addr); - return __raw_readb(data); -} -EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */ - -/* - * LEDs - */ - -static struct mfd_cell led_cell __initdata = { - .name = "leds-pasic3", -}; - -/* - * DS1WM - */ - -static int ds1wm_enable(struct platform_device *pdev) -{ - struct device *dev = pdev->dev.parent; - int c; - - c = pasic3_read_register(dev, 0x28); - pasic3_write_register(dev, 0x28, c & 0x7f); - - dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f); - return 0; -} - -static int ds1wm_disable(struct platform_device *pdev) -{ - struct device *dev = pdev->dev.parent; - int c; - - c = pasic3_read_register(dev, 0x28); - pasic3_write_register(dev, 0x28, c | 0x80); - - dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80); - return 0; -} - -static struct ds1wm_driver_data ds1wm_pdata = { - .active_high = 0, - .reset_recover_delay = 1, -}; - -static struct resource ds1wm_resources[] __initdata = { - [0] = { - .start = 0, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell ds1wm_cell __initdata = { - .name = "ds1wm", - .enable = ds1wm_enable, - .disable = ds1wm_disable, - .platform_data = &ds1wm_pdata, - .pdata_size = sizeof(ds1wm_pdata), - .num_resources = 2, - .resources = ds1wm_resources, -}; - -static int __init pasic3_probe(struct platform_device *pdev) -{ - struct pasic3_platform_data *pdata = pdev->dev.platform_data; - struct device *dev = &pdev->dev; - struct pasic3_data *asic; - struct resource *r; - int ret; - int irq = 0; - - r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (r) { - ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags & - (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)); - irq = r->start; - } - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) - return -ENXIO; - - if (!request_mem_region(r->start, resource_size(r), "pasic3")) - return -EBUSY; - - asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL); - if (!asic) - return -ENOMEM; - - platform_set_drvdata(pdev, asic); - - asic->mapping = ioremap(r->start, resource_size(r)); - if (!asic->mapping) { - dev_err(dev, "couldn't ioremap PASIC3\n"); - kfree(asic); - return -ENOMEM; - } - - /* calculate bus shift from mem resource */ - asic->bus_shift = (resource_size(r) - 5) >> 3; - - if (pdata && pdata->clock_rate) { - ds1wm_pdata.clock_rate = pdata->clock_rate; - /* the first 5 PASIC3 registers control the DS1WM */ - ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; - ret = mfd_add_devices(&pdev->dev, pdev->id, - &ds1wm_cell, 1, r, irq); - if (ret < 0) - dev_warn(dev, "failed to register DS1WM\n"); - } - - if (pdata && pdata->led_pdata) { - led_cell.platform_data = pdata->led_pdata; - led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); - ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); - if (ret < 0) - dev_warn(dev, "failed to register LED device\n"); - } - - return 0; -} - -static int pasic3_remove(struct platform_device *pdev) -{ - struct pasic3_data *asic = platform_get_drvdata(pdev); - struct resource *r; - - mfd_remove_devices(&pdev->dev); - - iounmap(asic->mapping); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, resource_size(r)); - kfree(asic); - return 0; -} - -MODULE_ALIAS("platform:pasic3"); - -static struct platform_driver pasic3_driver = { - .driver = { - .name = "pasic3", - }, - .remove = pasic3_remove, -}; - -static int __init pasic3_base_init(void) -{ - return platform_driver_probe(&pasic3_driver, pasic3_probe); -} - -static void __exit pasic3_base_exit(void) -{ - platform_driver_unregister(&pasic3_driver); -} - -module_init(pasic3_base_init); -module_exit(pasic3_base_exit); - -MODULE_AUTHOR("Philipp Zabel <philipp.zabel@gmail.com>"); -MODULE_DESCRIPTION("Core driver for HTC PASIC3"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/intel_msic.c b/ANDROID_3.4.5/drivers/mfd/intel_msic.c deleted file mode 100644 index b76657eb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/intel_msic.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * 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, - }, -}; - -module_platform_driver(intel_msic_driver); - -MODULE_DESCRIPTION("Driver for Intel MSIC"); -MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/janz-cmodio.c b/ANDROID_3.4.5/drivers/mfd/janz-cmodio.c deleted file mode 100644 index a9223ed1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/janz-cmodio.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Janz CMOD-IO MODULbus Carrier Board PCI Driver - * - * Copyright (c) 2010 Ira W. Snyder <iws@ovro.caltech.edu> - * - * Lots of inspiration and code was copied from drivers/mfd/sm501.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/mfd/core.h> - -#include <linux/mfd/janz.h> - -#define DRV_NAME "janz-cmodio" - -/* Size of each MODULbus module in PCI BAR4 */ -#define CMODIO_MODULBUS_SIZE 0x200 - -/* Maximum number of MODULbus modules on a CMOD-IO carrier board */ -#define CMODIO_MAX_MODULES 4 - -/* Module Parameters */ -static unsigned int num_modules = CMODIO_MAX_MODULES; -static char *modules[CMODIO_MAX_MODULES] = { - "empty", "empty", "empty", "empty", -}; - -module_param_array(modules, charp, &num_modules, S_IRUGO); -MODULE_PARM_DESC(modules, "MODULbus modules attached to the carrier board"); - -/* Unique Device Id */ -static unsigned int cmodio_id; - -struct cmodio_device { - /* Parent PCI device */ - struct pci_dev *pdev; - - /* PLX control registers */ - struct janz_cmodio_onboard_regs __iomem *ctrl; - - /* hex switch position */ - u8 hex; - - /* mfd-core API */ - struct mfd_cell cells[CMODIO_MAX_MODULES]; - struct resource resources[3 * CMODIO_MAX_MODULES]; - struct janz_platform_data pdata[CMODIO_MAX_MODULES]; -}; - -/* - * Subdevices using the mfd-core API - */ - -static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv, - char *name, unsigned int devno, - unsigned int modno) -{ - struct janz_platform_data *pdata; - struct mfd_cell *cell; - struct resource *res; - struct pci_dev *pci; - - pci = priv->pdev; - cell = &priv->cells[devno]; - res = &priv->resources[devno * 3]; - pdata = &priv->pdata[devno]; - - cell->name = name; - cell->resources = res; - cell->num_resources = 3; - - /* Setup the subdevice ID -- must be unique */ - cell->id = cmodio_id++; - - /* Add platform data */ - pdata->modno = modno; - cell->platform_data = pdata; - cell->pdata_size = sizeof(*pdata); - - /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */ - res->flags = IORESOURCE_MEM; - res->parent = &pci->resource[3]; - res->start = pci->resource[3].start + (CMODIO_MODULBUS_SIZE * modno); - res->end = res->start + CMODIO_MODULBUS_SIZE - 1; - res++; - - /* PLX Control Registers -- PCI BAR4 is interrupt and other registers */ - res->flags = IORESOURCE_MEM; - res->parent = &pci->resource[4]; - res->start = pci->resource[4].start; - res->end = pci->resource[4].end; - res++; - - /* - * IRQ - * - * The start and end fields are used as an offset to the irq_base - * parameter passed into the mfd_add_devices() function call. All - * devices share the same IRQ. - */ - res->flags = IORESOURCE_IRQ; - res->parent = NULL; - res->start = 0; - res->end = 0; - res++; - - return 0; -} - -/* Probe each submodule using kernel parameters */ -static int __devinit cmodio_probe_submodules(struct cmodio_device *priv) -{ - struct pci_dev *pdev = priv->pdev; - unsigned int num_probed = 0; - char *name; - int i; - - for (i = 0; i < num_modules; i++) { - name = modules[i]; - if (!strcmp(name, "") || !strcmp(name, "empty")) - continue; - - dev_dbg(&priv->pdev->dev, "MODULbus %d: name %s\n", i, name); - cmodio_setup_subdevice(priv, name, num_probed, i); - num_probed++; - } - - /* print an error message if no modules were probed */ - if (num_probed == 0) { - dev_err(&priv->pdev->dev, "no MODULbus modules specified, " - "please set the ``modules'' kernel " - "parameter according to your " - "hardware configuration\n"); - return -ENODEV; - } - - return mfd_add_devices(&pdev->dev, 0, priv->cells, - num_probed, NULL, pdev->irq); -} - -/* - * SYSFS Attributes - */ - -static ssize_t mbus_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cmodio_device *priv = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%x\n", priv->hex); -} - -static DEVICE_ATTR(modulbus_number, S_IRUGO, mbus_show, NULL); - -static struct attribute *cmodio_sysfs_attrs[] = { - &dev_attr_modulbus_number.attr, - NULL, -}; - -static const struct attribute_group cmodio_sysfs_attr_group = { - .attrs = cmodio_sysfs_attrs, -}; - -/* - * PCI Driver - */ - -static int __devinit cmodio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct cmodio_device *priv; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&dev->dev, "unable to allocate private data\n"); - ret = -ENOMEM; - goto out_return; - } - - pci_set_drvdata(dev, priv); - priv->pdev = dev; - - /* Hardware Initialization */ - ret = pci_enable_device(dev); - if (ret) { - dev_err(&dev->dev, "unable to enable device\n"); - goto out_free_priv; - } - - pci_set_master(dev); - ret = pci_request_regions(dev, DRV_NAME); - if (ret) { - dev_err(&dev->dev, "unable to request regions\n"); - goto out_pci_disable_device; - } - - /* Onboard configuration registers */ - priv->ctrl = pci_ioremap_bar(dev, 4); - if (!priv->ctrl) { - dev_err(&dev->dev, "unable to remap onboard regs\n"); - ret = -ENOMEM; - goto out_pci_release_regions; - } - - /* Read the hex switch on the carrier board */ - priv->hex = ioread8(&priv->ctrl->int_enable); - - /* Add the MODULbus number (hex switch value) to the device's sysfs */ - ret = sysfs_create_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); - if (ret) { - dev_err(&dev->dev, "unable to create sysfs attributes\n"); - goto out_unmap_ctrl; - } - - /* - * Disable all interrupt lines, each submodule will enable its - * own interrupt line if needed - */ - iowrite8(0xf, &priv->ctrl->int_disable); - - /* Register drivers for all submodules */ - ret = cmodio_probe_submodules(priv); - if (ret) { - dev_err(&dev->dev, "unable to probe submodules\n"); - goto out_sysfs_remove_group; - } - - return 0; - -out_sysfs_remove_group: - sysfs_remove_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); -out_unmap_ctrl: - iounmap(priv->ctrl); -out_pci_release_regions: - pci_release_regions(dev); -out_pci_disable_device: - pci_disable_device(dev); -out_free_priv: - kfree(priv); -out_return: - return ret; -} - -static void __devexit cmodio_pci_remove(struct pci_dev *dev) -{ - struct cmodio_device *priv = pci_get_drvdata(dev); - - mfd_remove_devices(&dev->dev); - sysfs_remove_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); - iounmap(priv->ctrl); - pci_release_regions(dev); - pci_disable_device(dev); - kfree(priv); -} - -#define PCI_VENDOR_ID_JANZ 0x13c3 - -/* The list of devices that this module will support */ -static DEFINE_PCI_DEVICE_TABLE(cmodio_pci_ids) = { - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 }, - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, cmodio_pci_ids); - -static struct pci_driver cmodio_pci_driver = { - .name = DRV_NAME, - .id_table = cmodio_pci_ids, - .probe = cmodio_pci_probe, - .remove = __devexit_p(cmodio_pci_remove), -}; - -/* - * Module Init / Exit - */ - -static int __init cmodio_init(void) -{ - return pci_register_driver(&cmodio_pci_driver); -} - -static void __exit cmodio_exit(void) -{ - pci_unregister_driver(&cmodio_pci_driver); -} - -MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); -MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver"); -MODULE_LICENSE("GPL"); - -module_init(cmodio_init); -module_exit(cmodio_exit); diff --git a/ANDROID_3.4.5/drivers/mfd/jz4740-adc.c b/ANDROID_3.4.5/drivers/mfd/jz4740-adc.c deleted file mode 100644 index 87662a17..00000000 --- a/ANDROID_3.4.5/drivers/mfd/jz4740-adc.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> - * JZ4740 SoC ADC driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * This driver synchronizes access to the JZ4740 ADC core between the - * JZ4740 battery and hwmon drivers. - */ - -#include <linux/err.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/spinlock.h> - -#include <linux/clk.h> -#include <linux/mfd/core.h> - -#include <linux/jz4740-adc.h> - - -#define JZ_REG_ADC_ENABLE 0x00 -#define JZ_REG_ADC_CFG 0x04 -#define JZ_REG_ADC_CTRL 0x08 -#define JZ_REG_ADC_STATUS 0x0c - -#define JZ_REG_ADC_TOUCHSCREEN_BASE 0x10 -#define JZ_REG_ADC_BATTERY_BASE 0x1c -#define JZ_REG_ADC_HWMON_BASE 0x20 - -#define JZ_ADC_ENABLE_TOUCH BIT(2) -#define JZ_ADC_ENABLE_BATTERY BIT(1) -#define JZ_ADC_ENABLE_ADCIN BIT(0) - -enum { - JZ_ADC_IRQ_ADCIN = 0, - JZ_ADC_IRQ_BATTERY, - JZ_ADC_IRQ_TOUCH, - JZ_ADC_IRQ_PENUP, - JZ_ADC_IRQ_PENDOWN, -}; - -struct jz4740_adc { - struct resource *mem; - void __iomem *base; - - int irq; - struct irq_chip_generic *gc; - - struct clk *clk; - atomic_t clk_ref; - - spinlock_t lock; -}; - -static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip_generic *gc = irq_desc_get_handler_data(desc); - uint8_t status; - unsigned int i; - - status = readb(gc->reg_base + JZ_REG_ADC_STATUS); - - for (i = 0; i < 5; ++i) { - if (status & BIT(i)) - generic_handle_irq(gc->irq_base + i); - } -} - - -/* Refcounting for the ADC clock is done in here instead of in the clock - * framework, because it is the only clock which is shared between multiple - * devices and thus is the only clock which needs refcounting */ -static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc) -{ - if (atomic_inc_return(&adc->clk_ref) == 1) - clk_enable(adc->clk); -} - -static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc) -{ - if (atomic_dec_return(&adc->clk_ref) == 0) - clk_disable(adc->clk); -} - -static inline void jz4740_adc_set_enabled(struct jz4740_adc *adc, int engine, - bool enabled) -{ - unsigned long flags; - uint8_t val; - - spin_lock_irqsave(&adc->lock, flags); - - val = readb(adc->base + JZ_REG_ADC_ENABLE); - if (enabled) - val |= BIT(engine); - else - val &= ~BIT(engine); - writeb(val, adc->base + JZ_REG_ADC_ENABLE); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static int jz4740_adc_cell_enable(struct platform_device *pdev) -{ - struct jz4740_adc *adc = dev_get_drvdata(pdev->dev.parent); - - jz4740_adc_clk_enable(adc); - jz4740_adc_set_enabled(adc, pdev->id, true); - - return 0; -} - -static int jz4740_adc_cell_disable(struct platform_device *pdev) -{ - struct jz4740_adc *adc = dev_get_drvdata(pdev->dev.parent); - - jz4740_adc_set_enabled(adc, pdev->id, false); - jz4740_adc_clk_disable(adc); - - return 0; -} - -int jz4740_adc_set_config(struct device *dev, uint32_t mask, uint32_t val) -{ - struct jz4740_adc *adc = dev_get_drvdata(dev); - unsigned long flags; - uint32_t cfg; - - if (!adc) - return -ENODEV; - - spin_lock_irqsave(&adc->lock, flags); - - cfg = readl(adc->base + JZ_REG_ADC_CFG); - - cfg &= ~mask; - cfg |= val; - - writel(cfg, adc->base + JZ_REG_ADC_CFG); - - spin_unlock_irqrestore(&adc->lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(jz4740_adc_set_config); - -static struct resource jz4740_hwmon_resources[] = { - { - .start = JZ_ADC_IRQ_ADCIN, - .flags = IORESOURCE_IRQ, - }, - { - .start = JZ_REG_ADC_HWMON_BASE, - .end = JZ_REG_ADC_HWMON_BASE + 3, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource jz4740_battery_resources[] = { - { - .start = JZ_ADC_IRQ_BATTERY, - .flags = IORESOURCE_IRQ, - }, - { - .start = JZ_REG_ADC_BATTERY_BASE, - .end = JZ_REG_ADC_BATTERY_BASE + 3, - .flags = IORESOURCE_MEM, - }, -}; - -static struct mfd_cell jz4740_adc_cells[] = { - { - .id = 0, - .name = "jz4740-hwmon", - .num_resources = ARRAY_SIZE(jz4740_hwmon_resources), - .resources = jz4740_hwmon_resources, - - .enable = jz4740_adc_cell_enable, - .disable = jz4740_adc_cell_disable, - }, - { - .id = 1, - .name = "jz4740-battery", - .num_resources = ARRAY_SIZE(jz4740_battery_resources), - .resources = jz4740_battery_resources, - - .enable = jz4740_adc_cell_enable, - .disable = jz4740_adc_cell_disable, - }, -}; - -static int __devinit jz4740_adc_probe(struct platform_device *pdev) -{ - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - struct jz4740_adc *adc; - struct resource *mem_base; - int ret; - int irq_base; - - adc = kmalloc(sizeof(*adc), GFP_KERNEL); - if (!adc) { - dev_err(&pdev->dev, "Failed to allocate driver structure\n"); - return -ENOMEM; - } - - adc->irq = platform_get_irq(pdev, 0); - if (adc->irq < 0) { - ret = adc->irq; - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); - goto err_free; - } - - irq_base = platform_get_irq(pdev, 1); - if (irq_base < 0) { - ret = irq_base; - dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret); - goto err_free; - } - - mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_base) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); - goto err_free; - } - - /* Only request the shared registers for the MFD driver */ - adc->mem = request_mem_region(mem_base->start, JZ_REG_ADC_STATUS, - pdev->name); - if (!adc->mem) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - goto err_free; - } - - adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem)); - if (!adc->base) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - goto err_release_mem_region; - } - - adc->clk = clk_get(&pdev->dev, "adc"); - if (IS_ERR(adc->clk)) { - ret = PTR_ERR(adc->clk); - dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); - goto err_iounmap; - } - - spin_lock_init(&adc->lock); - atomic_set(&adc->clk_ref, 0); - - platform_set_drvdata(pdev, adc); - - gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base, - handle_level_irq); - - ct = gc->chip_types; - ct->regs.mask = JZ_REG_ADC_CTRL; - ct->regs.ack = JZ_REG_ADC_STATUS; - ct->chip.irq_mask = irq_gc_mask_set_bit; - ct->chip.irq_unmask = irq_gc_mask_clr_bit; - ct->chip.irq_ack = irq_gc_ack_set_bit; - - irq_setup_generic_chip(gc, IRQ_MSK(5), 0, 0, IRQ_NOPROBE | IRQ_LEVEL); - - adc->gc = gc; - - irq_set_handler_data(adc->irq, gc); - irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); - - writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); - writeb(0xff, adc->base + JZ_REG_ADC_CTRL); - - ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, - ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); - if (ret < 0) - goto err_clk_put; - - return 0; - -err_clk_put: - clk_put(adc->clk); -err_iounmap: - platform_set_drvdata(pdev, NULL); - iounmap(adc->base); -err_release_mem_region: - release_mem_region(adc->mem->start, resource_size(adc->mem)); -err_free: - kfree(adc); - - return ret; -} - -static int __devexit jz4740_adc_remove(struct platform_device *pdev) -{ - struct jz4740_adc *adc = platform_get_drvdata(pdev); - - mfd_remove_devices(&pdev->dev); - - irq_remove_generic_chip(adc->gc, IRQ_MSK(5), IRQ_NOPROBE | IRQ_LEVEL, 0); - kfree(adc->gc); - irq_set_handler_data(adc->irq, NULL); - irq_set_chained_handler(adc->irq, NULL); - - iounmap(adc->base); - release_mem_region(adc->mem->start, resource_size(adc->mem)); - - clk_put(adc->clk); - - platform_set_drvdata(pdev, NULL); - - kfree(adc); - - return 0; -} - -static struct platform_driver jz4740_adc_driver = { - .probe = jz4740_adc_probe, - .remove = __devexit_p(jz4740_adc_remove), - .driver = { - .name = "jz4740-adc", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(jz4740_adc_driver); - -MODULE_DESCRIPTION("JZ4740 SoC ADC driver"); -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:jz4740-adc"); diff --git a/ANDROID_3.4.5/drivers/mfd/lpc_sch.c b/ANDROID_3.4.5/drivers/mfd/lpc_sch.c deleted file mode 100644 index abc42136..00000000 --- a/ANDROID_3.4.5/drivers/mfd/lpc_sch.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * lpc_sch.c - LPC interface for Intel Poulsbo SCH - * - * LPC bridge function of the Intel SCH contains many other - * functional units, such as Interrupt controllers, Timers, - * Power Management, System Management, GPIO, RTC, and LPC - * Configuration Registers. - * - * Copyright (c) 2010 CompuLab Ltd - * Author: Denis Turischev <denis@compulab.co.il> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License 2 as published - * by the Free Software Foundation. - * - * 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/acpi.h> -#include <linux/pci.h> -#include <linux/mfd/core.h> - -#define SMBASE 0x40 -#define SMBUS_IO_SIZE 64 - -#define GPIOBASE 0x44 -#define GPIO_IO_SIZE 64 - -#define WDTBASE 0x84 -#define WDT_IO_SIZE 64 - -static struct resource smbus_sch_resource = { - .flags = IORESOURCE_IO, -}; - - -static struct resource gpio_sch_resource = { - .flags = IORESOURCE_IO, -}; - -static struct mfd_cell lpc_sch_cells[] = { - { - .name = "isch_smbus", - .num_resources = 1, - .resources = &smbus_sch_resource, - }, - { - .name = "sch_gpio", - .num_resources = 1, - .resources = &gpio_sch_resource, - }, -}; - -static struct resource wdt_sch_resource = { - .flags = IORESOURCE_IO, -}; - -static struct mfd_cell tunnelcreek_cells[] = { - { - .name = "tunnelcreek_wdt", - .num_resources = 1, - .resources = &wdt_sch_resource, - }, -}; - -static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, lpc_sch_ids); - -static int __devinit lpc_sch_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - unsigned int base_addr_cfg; - unsigned short base_addr; - int i; - int ret; - - pci_read_config_dword(dev, SMBASE, &base_addr_cfg); - if (!(base_addr_cfg & (1 << 31))) { - dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n"); - return -ENODEV; - } - base_addr = (unsigned short)base_addr_cfg; - if (base_addr == 0) { - dev_err(&dev->dev, "I/O space for SMBus uninitialized\n"); - return -ENODEV; - } - - smbus_sch_resource.start = base_addr; - smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; - - pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); - if (!(base_addr_cfg & (1 << 31))) { - dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n"); - return -ENODEV; - } - base_addr = (unsigned short)base_addr_cfg; - if (base_addr == 0) { - dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); - return -ENODEV; - } - - gpio_sch_resource.start = base_addr; - gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; - - for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) - lpc_sch_cells[i].id = id->device; - - ret = mfd_add_devices(&dev->dev, 0, - lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); - if (ret) - goto out_dev; - - if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC) { - pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); - if (!(base_addr_cfg & (1 << 31))) { - dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); - ret = -ENODEV; - goto out_dev; - } - base_addr = (unsigned short)base_addr_cfg; - if (base_addr == 0) { - dev_err(&dev->dev, "I/O space for WDT uninitialized\n"); - ret = -ENODEV; - goto out_dev; - } - - wdt_sch_resource.start = base_addr; - wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; - - for (i = 0; i < ARRAY_SIZE(tunnelcreek_cells); i++) - tunnelcreek_cells[i].id = id->device; - - ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, - ARRAY_SIZE(tunnelcreek_cells), NULL, 0); - } - - return ret; -out_dev: - mfd_remove_devices(&dev->dev); - return ret; -} - -static void __devexit lpc_sch_remove(struct pci_dev *dev) -{ - mfd_remove_devices(&dev->dev); -} - -static struct pci_driver lpc_sch_driver = { - .name = "lpc_sch", - .id_table = lpc_sch_ids, - .probe = lpc_sch_probe, - .remove = __devexit_p(lpc_sch_remove), -}; - -static int __init lpc_sch_init(void) -{ - return pci_register_driver(&lpc_sch_driver); -} - -static void __exit lpc_sch_exit(void) -{ - pci_unregister_driver(&lpc_sch_driver); -} - -module_init(lpc_sch_init); -module_exit(lpc_sch_exit); - -MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); -MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/max8925-core.c b/ANDROID_3.4.5/drivers/mfd/max8925-core.c deleted file mode 100644 index ca881efe..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8925-core.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Base driver for Maxim MAX8925 - * - * Copyright (C) 2009-2010 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/mfd/core.h> -#include <linux/mfd/max8925.h> - -static struct resource backlight_resources[] = { - { - .name = "max8925-backlight", - .start = MAX8925_WLED_MODE_CNTL, - .end = MAX8925_WLED_CNTL, - .flags = IORESOURCE_IO, - }, -}; - -static struct mfd_cell backlight_devs[] = { - { - .name = "max8925-backlight", - .num_resources = 1, - .resources = &backlight_resources[0], - .id = -1, - }, -}; - -static struct resource touch_resources[] = { - { - .name = "max8925-tsc", - .start = MAX8925_TSC_IRQ, - .end = MAX8925_ADC_RES_END, - .flags = IORESOURCE_IO, - }, -}; - -static struct mfd_cell touch_devs[] = { - { - .name = "max8925-touch", - .num_resources = 1, - .resources = &touch_resources[0], - .id = -1, - }, -}; - -static struct resource power_supply_resources[] = { - { - .name = "max8925-power", - .start = MAX8925_CHG_IRQ1, - .end = MAX8925_CHG_IRQ1_MASK, - .flags = IORESOURCE_IO, - }, -}; - -static struct mfd_cell power_devs[] = { - { - .name = "max8925-power", - .num_resources = 1, - .resources = &power_supply_resources[0], - .id = -1, - }, -}; - -static struct resource rtc_resources[] = { - { - .name = "max8925-rtc", - .start = MAX8925_RTC_IRQ, - .end = MAX8925_RTC_IRQ_MASK, - .flags = IORESOURCE_IO, - }, -}; - -static struct mfd_cell rtc_devs[] = { - { - .name = "max8925-rtc", - .num_resources = 1, - .resources = &rtc_resources[0], - .id = -1, - }, -}; - -static struct resource onkey_resources[] = { - { - .name = "max8925-onkey", - .start = MAX8925_IRQ_GPM_SW_R, - .end = MAX8925_IRQ_GPM_SW_R, - .flags = IORESOURCE_IRQ, - }, { - .name = "max8925-onkey", - .start = MAX8925_IRQ_GPM_SW_F, - .end = MAX8925_IRQ_GPM_SW_F, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell onkey_devs[] = { - { - .name = "max8925-onkey", - .num_resources = 2, - .resources = &onkey_resources[0], - .id = -1, - }, -}; - -#define MAX8925_REG_RESOURCE(_start, _end) \ -{ \ - .start = MAX8925_##_start, \ - .end = MAX8925_##_end, \ - .flags = IORESOURCE_IO, \ -} - -static struct resource regulator_resources[] = { - MAX8925_REG_RESOURCE(SDCTL1, SDCTL1), - MAX8925_REG_RESOURCE(SDCTL2, SDCTL2), - MAX8925_REG_RESOURCE(SDCTL3, SDCTL3), - MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1), - MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2), - MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3), - MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4), - MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5), - MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6), - MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7), - MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8), - MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9), - MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10), - MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11), - MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12), - MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13), - MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14), - MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15), - MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16), - MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17), - MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18), - MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19), - MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20), -}; - -#define MAX8925_REG_DEVS(_id) \ -{ \ - .name = "max8925-regulator", \ - .num_resources = 1, \ - .resources = ®ulator_resources[MAX8925_ID_##_id], \ - .id = MAX8925_ID_##_id, \ -} - -static struct mfd_cell regulator_devs[] = { - MAX8925_REG_DEVS(SD1), - MAX8925_REG_DEVS(SD2), - MAX8925_REG_DEVS(SD3), - MAX8925_REG_DEVS(LDO1), - MAX8925_REG_DEVS(LDO2), - MAX8925_REG_DEVS(LDO3), - MAX8925_REG_DEVS(LDO4), - MAX8925_REG_DEVS(LDO5), - MAX8925_REG_DEVS(LDO6), - MAX8925_REG_DEVS(LDO7), - MAX8925_REG_DEVS(LDO8), - MAX8925_REG_DEVS(LDO9), - MAX8925_REG_DEVS(LDO10), - MAX8925_REG_DEVS(LDO11), - MAX8925_REG_DEVS(LDO12), - MAX8925_REG_DEVS(LDO13), - MAX8925_REG_DEVS(LDO14), - MAX8925_REG_DEVS(LDO15), - MAX8925_REG_DEVS(LDO16), - MAX8925_REG_DEVS(LDO17), - MAX8925_REG_DEVS(LDO18), - MAX8925_REG_DEVS(LDO19), - MAX8925_REG_DEVS(LDO20), -}; - -enum { - FLAGS_ADC = 1, /* register in ADC component */ - FLAGS_RTC, /* register in RTC component */ -}; - -struct max8925_irq_data { - int reg; - int mask_reg; - int enable; /* enable or not */ - int offs; /* bit offset in mask register */ - int flags; - int tsc_irq; -}; - -static struct max8925_irq_data max8925_irqs[] = { - [MAX8925_IRQ_VCHG_DC_OVP] = { - .reg = MAX8925_CHG_IRQ1, - .mask_reg = MAX8925_CHG_IRQ1_MASK, - .offs = 1 << 0, - }, - [MAX8925_IRQ_VCHG_DC_F] = { - .reg = MAX8925_CHG_IRQ1, - .mask_reg = MAX8925_CHG_IRQ1_MASK, - .offs = 1 << 1, - }, - [MAX8925_IRQ_VCHG_DC_R] = { - .reg = MAX8925_CHG_IRQ1, - .mask_reg = MAX8925_CHG_IRQ1_MASK, - .offs = 1 << 2, - }, - [MAX8925_IRQ_VCHG_THM_OK_R] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 0, - }, - [MAX8925_IRQ_VCHG_THM_OK_F] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 1, - }, - [MAX8925_IRQ_VCHG_SYSLOW_F] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 2, - }, - [MAX8925_IRQ_VCHG_SYSLOW_R] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 3, - }, - [MAX8925_IRQ_VCHG_RST] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 4, - }, - [MAX8925_IRQ_VCHG_DONE] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 5, - }, - [MAX8925_IRQ_VCHG_TOPOFF] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 6, - }, - [MAX8925_IRQ_VCHG_TMR_FAULT] = { - .reg = MAX8925_CHG_IRQ2, - .mask_reg = MAX8925_CHG_IRQ2_MASK, - .offs = 1 << 7, - }, - [MAX8925_IRQ_GPM_RSTIN] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 0, - }, - [MAX8925_IRQ_GPM_MPL] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 1, - }, - [MAX8925_IRQ_GPM_SW_3SEC] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 2, - }, - [MAX8925_IRQ_GPM_EXTON_F] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 3, - }, - [MAX8925_IRQ_GPM_EXTON_R] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 4, - }, - [MAX8925_IRQ_GPM_SW_1SEC] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 5, - }, - [MAX8925_IRQ_GPM_SW_F] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 6, - }, - [MAX8925_IRQ_GPM_SW_R] = { - .reg = MAX8925_ON_OFF_IRQ1, - .mask_reg = MAX8925_ON_OFF_IRQ1_MASK, - .offs = 1 << 7, - }, - [MAX8925_IRQ_GPM_SYSCKEN_F] = { - .reg = MAX8925_ON_OFF_IRQ2, - .mask_reg = MAX8925_ON_OFF_IRQ2_MASK, - .offs = 1 << 0, - }, - [MAX8925_IRQ_GPM_SYSCKEN_R] = { - .reg = MAX8925_ON_OFF_IRQ2, - .mask_reg = MAX8925_ON_OFF_IRQ2_MASK, - .offs = 1 << 1, - }, - [MAX8925_IRQ_RTC_ALARM1] = { - .reg = MAX8925_RTC_IRQ, - .mask_reg = MAX8925_RTC_IRQ_MASK, - .offs = 1 << 2, - .flags = FLAGS_RTC, - }, - [MAX8925_IRQ_RTC_ALARM0] = { - .reg = MAX8925_RTC_IRQ, - .mask_reg = MAX8925_RTC_IRQ_MASK, - .offs = 1 << 3, - .flags = FLAGS_RTC, - }, - [MAX8925_IRQ_TSC_STICK] = { - .reg = MAX8925_TSC_IRQ, - .mask_reg = MAX8925_TSC_IRQ_MASK, - .offs = 1 << 0, - .flags = FLAGS_ADC, - .tsc_irq = 1, - }, - [MAX8925_IRQ_TSC_NSTICK] = { - .reg = MAX8925_TSC_IRQ, - .mask_reg = MAX8925_TSC_IRQ_MASK, - .offs = 1 << 1, - .flags = FLAGS_ADC, - .tsc_irq = 1, - }, -}; - -static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip, - int irq) -{ - return &max8925_irqs[irq - chip->irq_base]; -} - -static irqreturn_t max8925_irq(int irq, void *data) -{ - struct max8925_chip *chip = data; - struct max8925_irq_data *irq_data; - struct i2c_client *i2c; - int read_reg = -1, value = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { - irq_data = &max8925_irqs[i]; - /* TSC IRQ should be serviced in max8925_tsc_irq() */ - if (irq_data->tsc_irq) - continue; - if (irq_data->flags == FLAGS_RTC) - i2c = chip->rtc; - else if (irq_data->flags == FLAGS_ADC) - i2c = chip->adc; - else - i2c = chip->i2c; - if (read_reg != irq_data->reg) { - read_reg = irq_data->reg; - value = max8925_reg_read(i2c, irq_data->reg); - } - if (value & irq_data->enable) - handle_nested_irq(chip->irq_base + i); - } - return IRQ_HANDLED; -} - -static irqreturn_t max8925_tsc_irq(int irq, void *data) -{ - struct max8925_chip *chip = data; - struct max8925_irq_data *irq_data; - struct i2c_client *i2c; - int read_reg = -1, value = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { - irq_data = &max8925_irqs[i]; - /* non TSC IRQ should be serviced in max8925_irq() */ - if (!irq_data->tsc_irq) - continue; - if (irq_data->flags == FLAGS_RTC) - i2c = chip->rtc; - else if (irq_data->flags == FLAGS_ADC) - i2c = chip->adc; - else - i2c = chip->i2c; - if (read_reg != irq_data->reg) { - read_reg = irq_data->reg; - value = max8925_reg_read(i2c, irq_data->reg); - } - if (value & irq_data->enable) - handle_nested_irq(chip->irq_base + i); - } - return IRQ_HANDLED; -} - -static void max8925_irq_lock(struct irq_data *data) -{ - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - - mutex_lock(&chip->irq_lock); -} - -static void max8925_irq_sync_unlock(struct irq_data *data) -{ - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - struct max8925_irq_data *irq_data; - static unsigned char cache_chg[2] = {0xff, 0xff}; - static unsigned char cache_on[2] = {0xff, 0xff}; - static unsigned char cache_rtc = 0xff, cache_tsc = 0xff; - unsigned char irq_chg[2], irq_on[2]; - unsigned char irq_rtc, irq_tsc; - int i; - - /* Load cached value. In initial, all IRQs are masked */ - irq_chg[0] = cache_chg[0]; - irq_chg[1] = cache_chg[1]; - irq_on[0] = cache_on[0]; - irq_on[1] = cache_on[1]; - irq_rtc = cache_rtc; - irq_tsc = cache_tsc; - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { - irq_data = &max8925_irqs[i]; - /* 1 -- disable, 0 -- enable */ - switch (irq_data->mask_reg) { - case MAX8925_CHG_IRQ1_MASK: - irq_chg[0] &= ~irq_data->enable; - break; - case MAX8925_CHG_IRQ2_MASK: - irq_chg[1] &= ~irq_data->enable; - break; - case MAX8925_ON_OFF_IRQ1_MASK: - irq_on[0] &= ~irq_data->enable; - break; - case MAX8925_ON_OFF_IRQ2_MASK: - irq_on[1] &= ~irq_data->enable; - break; - case MAX8925_RTC_IRQ_MASK: - irq_rtc &= ~irq_data->enable; - break; - case MAX8925_TSC_IRQ_MASK: - irq_tsc &= ~irq_data->enable; - break; - default: - dev_err(chip->dev, "wrong IRQ\n"); - break; - } - } - /* update mask into registers */ - if (cache_chg[0] != irq_chg[0]) { - cache_chg[0] = irq_chg[0]; - max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, - irq_chg[0]); - } - if (cache_chg[1] != irq_chg[1]) { - cache_chg[1] = irq_chg[1]; - max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, - irq_chg[1]); - } - if (cache_on[0] != irq_on[0]) { - cache_on[0] = irq_on[0]; - max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, - irq_on[0]); - } - if (cache_on[1] != irq_on[1]) { - cache_on[1] = irq_on[1]; - max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, - irq_on[1]); - } - if (cache_rtc != irq_rtc) { - cache_rtc = irq_rtc; - max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc); - } - if (cache_tsc != irq_tsc) { - cache_tsc = irq_tsc; - max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc); - } - - mutex_unlock(&chip->irq_lock); -} - -static void max8925_irq_enable(struct irq_data *data) -{ - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - max8925_irqs[data->irq - chip->irq_base].enable - = max8925_irqs[data->irq - chip->irq_base].offs; -} - -static void max8925_irq_disable(struct irq_data *data) -{ - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - max8925_irqs[data->irq - chip->irq_base].enable = 0; -} - -static struct irq_chip max8925_irq_chip = { - .name = "max8925", - .irq_bus_lock = max8925_irq_lock, - .irq_bus_sync_unlock = max8925_irq_sync_unlock, - .irq_enable = max8925_irq_enable, - .irq_disable = max8925_irq_disable, -}; - -static int max8925_irq_init(struct max8925_chip *chip, int irq, - struct max8925_platform_data *pdata) -{ - unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; - int i, ret; - int __irq; - - if (!pdata || !pdata->irq_base) { - dev_warn(chip->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } - /* clear all interrupts */ - max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); - max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); - max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1); - max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2); - max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ); - max8925_reg_read(chip->adc, MAX8925_TSC_IRQ); - /* mask all interrupts except for TSC */ - max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0); - max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0); - max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff); - max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff); - max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff); - max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff); - max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); - - mutex_init(&chip->irq_lock); - chip->core_irq = irq; - chip->irq_base = pdata->irq_base; - - /* register with genirq */ - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { - __irq = i + chip->irq_base; - irq_set_chip_data(__irq, chip); - irq_set_chip_and_handler(__irq, &max8925_irq_chip, - handle_edge_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#else - irq_set_noprobe(__irq); -#endif - } - if (!irq) { - dev_warn(chip->dev, "No interrupt support on core IRQ\n"); - goto tsc_irq; - } - - ret = request_threaded_irq(irq, NULL, max8925_irq, flags, - "max8925", chip); - if (ret) { - dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); - chip->core_irq = 0; - } - -tsc_irq: - /* mask TSC interrupt */ - max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); - - if (!pdata->tsc_irq) { - dev_warn(chip->dev, "No interrupt support on TSC IRQ\n"); - return 0; - } - chip->tsc_irq = pdata->tsc_irq; - - ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, - flags, "max8925-tsc", chip); - if (ret) { - dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret); - chip->tsc_irq = 0; - } - return 0; -} - -int __devinit max8925_device_init(struct max8925_chip *chip, - struct max8925_platform_data *pdata) -{ - int ret; - - max8925_irq_init(chip, chip->i2c->irq, pdata); - - if (pdata && (pdata->power || pdata->touch)) { - /* enable ADC to control internal reference */ - max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1); - /* enable internal reference for ADC */ - max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2); - /* check for internal reference IRQ */ - do { - ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ); - } while (ret & MAX8925_NREF_OK); - /* enaable ADC scheduler, interval is 1 second */ - max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2); - } - - /* enable Momentary Power Loss */ - max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4); - - ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], - ARRAY_SIZE(rtc_devs), - &rtc_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add rtc subdev\n"); - goto out; - } - - ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], - ARRAY_SIZE(onkey_devs), - &onkey_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add onkey subdev\n"); - goto out_dev; - } - - if (pdata) { - ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], - ARRAY_SIZE(regulator_devs), - ®ulator_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add regulator subdev\n"); - goto out_dev; - } - } - - if (pdata && pdata->backlight) { - ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], - ARRAY_SIZE(backlight_devs), - &backlight_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add backlight subdev\n"); - goto out_dev; - } - } - - if (pdata && pdata->power) { - ret = mfd_add_devices(chip->dev, 0, &power_devs[0], - ARRAY_SIZE(power_devs), - &power_supply_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add power supply " - "subdev\n"); - goto out_dev; - } - } - - if (pdata && pdata->touch) { - ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], - ARRAY_SIZE(touch_devs), - &touch_resources[0], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add touch subdev\n"); - goto out_dev; - } - } - - return 0; -out_dev: - mfd_remove_devices(chip->dev); -out: - return ret; -} - -void __devexit max8925_device_exit(struct max8925_chip *chip) -{ - if (chip->core_irq) - free_irq(chip->core_irq, chip); - if (chip->tsc_irq) - free_irq(chip->tsc_irq, chip); - mfd_remove_devices(chip->dev); -} - - -MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925"); -MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/max8925-i2c.c b/ANDROID_3.4.5/drivers/mfd/max8925-i2c.c deleted file mode 100644 index d9e4b36e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8925-i2c.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * I2C driver for Maxim MAX8925 - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/mfd/max8925.h> -#include <linux/slab.h> - -#define RTC_I2C_ADDR 0x68 -#define ADC_I2C_ADDR 0x47 - -static inline int max8925_read_device(struct i2c_client *i2c, - int reg, int bytes, void *dest) -{ - int ret; - - if (bytes > 1) - ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest); - else { - ret = i2c_smbus_read_byte_data(i2c, reg); - if (ret < 0) - return ret; - *(unsigned char *)dest = (unsigned char)ret; - } - return ret; -} - -static inline int max8925_write_device(struct i2c_client *i2c, - int reg, int bytes, void *src) -{ - unsigned char buf[bytes + 1]; - int ret; - - buf[0] = (unsigned char)reg; - memcpy(&buf[1], src, bytes); - - ret = i2c_master_send(i2c, buf, bytes + 1); - if (ret < 0) - return ret; - return 0; -} - -int max8925_reg_read(struct i2c_client *i2c, int reg) -{ - struct max8925_chip *chip = i2c_get_clientdata(i2c); - unsigned char data = 0; - int ret; - - mutex_lock(&chip->io_lock); - ret = max8925_read_device(i2c, reg, 1, &data); - mutex_unlock(&chip->io_lock); - - if (ret < 0) - return ret; - else - return (int)data; -} -EXPORT_SYMBOL(max8925_reg_read); - -int max8925_reg_write(struct i2c_client *i2c, int reg, - unsigned char data) -{ - struct max8925_chip *chip = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&chip->io_lock); - ret = max8925_write_device(i2c, reg, 1, &data); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(max8925_reg_write); - -int max8925_bulk_read(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - struct max8925_chip *chip = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&chip->io_lock); - ret = max8925_read_device(i2c, reg, count, buf); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(max8925_bulk_read); - -int max8925_bulk_write(struct i2c_client *i2c, int reg, - int count, unsigned char *buf) -{ - struct max8925_chip *chip = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&chip->io_lock); - ret = max8925_write_device(i2c, reg, count, buf); - mutex_unlock(&chip->io_lock); - - return ret; -} -EXPORT_SYMBOL(max8925_bulk_write); - -int max8925_set_bits(struct i2c_client *i2c, int reg, - unsigned char mask, unsigned char data) -{ - struct max8925_chip *chip = i2c_get_clientdata(i2c); - unsigned char value; - int ret; - - mutex_lock(&chip->io_lock); - ret = max8925_read_device(i2c, reg, 1, &value); - if (ret < 0) - goto out; - value &= ~mask; - value |= data; - ret = max8925_write_device(i2c, reg, 1, &value); -out: - mutex_unlock(&chip->io_lock); - return ret; -} -EXPORT_SYMBOL(max8925_set_bits); - - -static const struct i2c_device_id max8925_id_table[] = { - { "max8925", 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, max8925_id_table); - -static int __devinit max8925_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct max8925_platform_data *pdata = client->dev.platform_data; - static struct max8925_chip *chip; - - if (!pdata) { - pr_info("%s: platform data is missing\n", __func__); - return -EINVAL; - } - - chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - chip->i2c = client; - chip->dev = &client->dev; - i2c_set_clientdata(client, chip); - dev_set_drvdata(chip->dev, chip); - mutex_init(&chip->io_lock); - - chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); - i2c_set_clientdata(chip->rtc, chip); - - chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); - i2c_set_clientdata(chip->adc, chip); - - device_init_wakeup(&client->dev, 1); - - max8925_device_init(chip, pdata); - - return 0; -} - -static int __devexit max8925_remove(struct i2c_client *client) -{ - struct max8925_chip *chip = i2c_get_clientdata(client); - - max8925_device_exit(chip); - i2c_unregister_device(chip->adc); - i2c_unregister_device(chip->rtc); - kfree(chip); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int max8925_suspend(struct device *dev) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - struct max8925_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev) && chip->wakeup_flag) - enable_irq_wake(chip->core_irq); - return 0; -} - -static int max8925_resume(struct device *dev) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - struct max8925_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev) && chip->wakeup_flag) - disable_irq_wake(chip->core_irq); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); - -static struct i2c_driver max8925_driver = { - .driver = { - .name = "max8925", - .owner = THIS_MODULE, - .pm = &max8925_pm_ops, - }, - .probe = max8925_probe, - .remove = __devexit_p(max8925_remove), - .id_table = max8925_id_table, -}; - -static int __init max8925_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&max8925_driver); - if (ret != 0) - pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); - return ret; -} -subsys_initcall(max8925_i2c_init); - -static void __exit max8925_i2c_exit(void) -{ - i2c_del_driver(&max8925_driver); -} -module_exit(max8925_i2c_exit); - -MODULE_DESCRIPTION("I2C Driver for Maxim 8925"); -MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/max8997-irq.c b/ANDROID_3.4.5/drivers/mfd/max8997-irq.c deleted file mode 100644 index 09274cf7..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8997-irq.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * max8997-irq.c - Interrupt controller support for MAX8997 - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * MyungJoo Ham <myungjoo.ham@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8998-irq.c - */ - -#include <linux/err.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/mfd/max8997.h> -#include <linux/mfd/max8997-private.h> - -static const u8 max8997_mask_reg[] = { - [PMIC_INT1] = MAX8997_REG_INT1MSK, - [PMIC_INT2] = MAX8997_REG_INT2MSK, - [PMIC_INT3] = MAX8997_REG_INT3MSK, - [PMIC_INT4] = MAX8997_REG_INT4MSK, - [FUEL_GAUGE] = MAX8997_REG_INVALID, - [MUIC_INT1] = MAX8997_MUIC_REG_INTMASK1, - [MUIC_INT2] = MAX8997_MUIC_REG_INTMASK2, - [MUIC_INT3] = MAX8997_MUIC_REG_INTMASK3, - [GPIO_LOW] = MAX8997_REG_INVALID, - [GPIO_HI] = MAX8997_REG_INVALID, - [FLASH_STATUS] = MAX8997_REG_INVALID, -}; - -static struct i2c_client *get_i2c(struct max8997_dev *max8997, - enum max8997_irq_source src) -{ - switch (src) { - case PMIC_INT1 ... PMIC_INT4: - return max8997->i2c; - case FUEL_GAUGE: - return NULL; - case MUIC_INT1 ... MUIC_INT3: - return max8997->muic; - case GPIO_LOW ... GPIO_HI: - return max8997->i2c; - case FLASH_STATUS: - return max8997->i2c; - default: - return ERR_PTR(-EINVAL); - } -} - -struct max8997_irq_data { - int mask; - enum max8997_irq_source group; -}; - -#define DECLARE_IRQ(idx, _group, _mask) \ - [(idx)] = { .group = (_group), .mask = (_mask) } -static const struct max8997_irq_data max8997_irqs[] = { - DECLARE_IRQ(MAX8997_PMICIRQ_PWRONR, PMIC_INT1, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_PWRONF, PMIC_INT1, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_PWRON1SEC, PMIC_INT1, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGONR, PMIC_INT1, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGONF, PMIC_INT1, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT2, PMIC_INT1, 1 << 6), - DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT1, PMIC_INT1, 1 << 7), - - DECLARE_IRQ(MAX8997_PMICIRQ_JIGR, PMIC_INT2, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGF, PMIC_INT2, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_MR, PMIC_INT2, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS1OK, PMIC_INT2, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS2OK, PMIC_INT2, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS3OK, PMIC_INT2, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS4OK, PMIC_INT2, 1 << 6), - - DECLARE_IRQ(MAX8997_PMICIRQ_CHGINS, PMIC_INT3, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_CHGRM, PMIC_INT3, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_DCINOVP, PMIC_INT3, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_TOPOFFR, PMIC_INT3, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_CHGRSTF, PMIC_INT3, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_MBCHGTMEXPD, PMIC_INT3, 1 << 7), - - DECLARE_IRQ(MAX8997_PMICIRQ_RTC60S, PMIC_INT4, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_RTCA1, PMIC_INT4, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_RTCA2, PMIC_INT4, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_SMPL_INT, PMIC_INT4, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_RTC1S, PMIC_INT4, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_WTSR, PMIC_INT4, 1 << 5), - - DECLARE_IRQ(MAX8997_MUICIRQ_ADCError, MUIC_INT1, 1 << 2), - DECLARE_IRQ(MAX8997_MUICIRQ_ADCLow, MUIC_INT1, 1 << 1), - DECLARE_IRQ(MAX8997_MUICIRQ_ADC, MUIC_INT1, 1 << 0), - - DECLARE_IRQ(MAX8997_MUICIRQ_VBVolt, MUIC_INT2, 1 << 4), - DECLARE_IRQ(MAX8997_MUICIRQ_DBChg, MUIC_INT2, 1 << 3), - DECLARE_IRQ(MAX8997_MUICIRQ_DCDTmr, MUIC_INT2, 1 << 2), - DECLARE_IRQ(MAX8997_MUICIRQ_ChgDetRun, MUIC_INT2, 1 << 1), - DECLARE_IRQ(MAX8997_MUICIRQ_ChgTyp, MUIC_INT2, 1 << 0), - - DECLARE_IRQ(MAX8997_MUICIRQ_OVP, MUIC_INT3, 1 << 2), -}; - -static void max8997_irq_lock(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - - mutex_lock(&max8997->irqlock); -} - -static void max8997_irq_sync_unlock(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - int i; - - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { - u8 mask_reg = max8997_mask_reg[i]; - struct i2c_client *i2c = get_i2c(max8997, i); - - if (mask_reg == MAX8997_REG_INVALID || - IS_ERR_OR_NULL(i2c)) - continue; - max8997->irq_masks_cache[i] = max8997->irq_masks_cur[i]; - - max8997_write_reg(i2c, max8997_mask_reg[i], - max8997->irq_masks_cur[i]); - } - - mutex_unlock(&max8997->irqlock); -} - -static const inline struct max8997_irq_data * -irq_to_max8997_irq(struct max8997_dev *max8997, int irq) -{ - return &max8997_irqs[irq - max8997->irq_base]; -} - -static void max8997_irq_mask(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, - data->irq); - - max8997->irq_masks_cur[irq_data->group] |= irq_data->mask; -} - -static void max8997_irq_unmask(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, - data->irq); - - max8997->irq_masks_cur[irq_data->group] &= ~irq_data->mask; -} - -static struct irq_chip max8997_irq_chip = { - .name = "max8997", - .irq_bus_lock = max8997_irq_lock, - .irq_bus_sync_unlock = max8997_irq_sync_unlock, - .irq_mask = max8997_irq_mask, - .irq_unmask = max8997_irq_unmask, -}; - -#define MAX8997_IRQSRC_PMIC (1 << 1) -#define MAX8997_IRQSRC_FUELGAUGE (1 << 2) -#define MAX8997_IRQSRC_MUIC (1 << 3) -#define MAX8997_IRQSRC_GPIO (1 << 4) -#define MAX8997_IRQSRC_FLASH (1 << 5) -static irqreturn_t max8997_irq_thread(int irq, void *data) -{ - struct max8997_dev *max8997 = data; - u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; - u8 irq_src; - int ret; - int i; - - ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); - if (ret < 0) { - dev_err(max8997->dev, "Failed to read interrupt source: %d\n", - ret); - return IRQ_NONE; - } - - if (irq_src & MAX8997_IRQSRC_PMIC) { - /* PMIC INT1 ~ INT4 */ - max8997_bulk_read(max8997->i2c, MAX8997_REG_INT1, 4, - &irq_reg[PMIC_INT1]); - } - if (irq_src & MAX8997_IRQSRC_FUELGAUGE) { - /* - * TODO: FUEL GAUGE - * - * This is to be supported by Max17042 driver. When - * an interrupt incurs here, it should be relayed to a - * Max17042 device that is connected (probably by - * platform-data). However, we do not have interrupt - * handling in Max17042 driver currently. The Max17042 IRQ - * driver should be ready to be used as a stand-alone device and - * a Max8997-dependent device. Because it is not ready in - * Max17042-side and it is not too critical in operating - * Max8997, we do not implement this in initial releases. - */ - irq_reg[FUEL_GAUGE] = 0; - } - if (irq_src & MAX8997_IRQSRC_MUIC) { - /* MUIC INT1 ~ INT3 */ - max8997_bulk_read(max8997->muic, MAX8997_MUIC_REG_INT1, 3, - &irq_reg[MUIC_INT1]); - } - if (irq_src & MAX8997_IRQSRC_GPIO) { - /* GPIO Interrupt */ - u8 gpio_info[MAX8997_NUM_GPIO]; - - irq_reg[GPIO_LOW] = 0; - irq_reg[GPIO_HI] = 0; - - max8997_bulk_read(max8997->i2c, MAX8997_REG_GPIOCNTL1, - MAX8997_NUM_GPIO, gpio_info); - for (i = 0; i < MAX8997_NUM_GPIO; i++) { - bool interrupt = false; - - switch (gpio_info[i] & MAX8997_GPIO_INT_MASK) { - case MAX8997_GPIO_INT_BOTH: - if (max8997->gpio_status[i] != gpio_info[i]) - interrupt = true; - break; - case MAX8997_GPIO_INT_RISE: - if ((max8997->gpio_status[i] != gpio_info[i]) && - (gpio_info[i] & MAX8997_GPIO_DATA_MASK)) - interrupt = true; - break; - case MAX8997_GPIO_INT_FALL: - if ((max8997->gpio_status[i] != gpio_info[i]) && - !(gpio_info[i] & MAX8997_GPIO_DATA_MASK)) - interrupt = true; - break; - default: - break; - } - - if (interrupt) { - if (i < 8) - irq_reg[GPIO_LOW] |= (1 << i); - else - irq_reg[GPIO_HI] |= (1 << (i - 8)); - } - - } - } - if (irq_src & MAX8997_IRQSRC_FLASH) { - /* Flash Status Interrupt */ - ret = max8997_read_reg(max8997->i2c, MAX8997_REG_FLASHSTATUS, - &irq_reg[FLASH_STATUS]); - } - - /* Apply masking */ - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) - irq_reg[i] &= ~max8997->irq_masks_cur[i]; - - /* Report */ - for (i = 0; i < MAX8997_IRQ_NR; i++) { - if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) - handle_nested_irq(max8997->irq_base + i); - } - - return IRQ_HANDLED; -} - -int max8997_irq_resume(struct max8997_dev *max8997) -{ - if (max8997->irq && max8997->irq_base) - max8997_irq_thread(max8997->irq_base, max8997); - return 0; -} - -int max8997_irq_init(struct max8997_dev *max8997) -{ - int i; - int cur_irq; - int ret; - u8 val; - - if (!max8997->irq) { - dev_warn(max8997->dev, "No interrupt specified.\n"); - max8997->irq_base = 0; - return 0; - } - - if (!max8997->irq_base) { - dev_err(max8997->dev, "No interrupt base specified.\n"); - return 0; - } - - mutex_init(&max8997->irqlock); - - /* Mask individual interrupt sources */ - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { - struct i2c_client *i2c; - - max8997->irq_masks_cur[i] = 0xff; - max8997->irq_masks_cache[i] = 0xff; - i2c = get_i2c(max8997, i); - - if (IS_ERR_OR_NULL(i2c)) - continue; - if (max8997_mask_reg[i] == MAX8997_REG_INVALID) - continue; - - max8997_write_reg(i2c, max8997_mask_reg[i], 0xff); - } - - for (i = 0; i < MAX8997_NUM_GPIO; i++) { - max8997->gpio_status[i] = (max8997_read_reg(max8997->i2c, - MAX8997_REG_GPIOCNTL1 + i, - &val) - & MAX8997_GPIO_DATA_MASK) ? - true : false; - } - - /* Register with genirq */ - for (i = 0; i < MAX8997_IRQ_NR; i++) { - cur_irq = i + max8997->irq_base; - irq_set_chip_data(cur_irq, max8997); - irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "max8997-irq", max8997); - - if (ret) { - dev_err(max8997->dev, "Failed to request IRQ %d: %d\n", - max8997->irq, ret); - return ret; - } - - if (!max8997->ono) - return 0; - - ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "max8997-ono", max8997); - - if (ret) - dev_err(max8997->dev, "Failed to request ono-IRQ %d: %d\n", - max8997->ono, ret); - - return 0; -} - -void max8997_irq_exit(struct max8997_dev *max8997) -{ - if (max8997->ono) - free_irq(max8997->ono, max8997); - - if (max8997->irq) - free_irq(max8997->irq, max8997); -} diff --git a/ANDROID_3.4.5/drivers/mfd/max8997.c b/ANDROID_3.4.5/drivers/mfd/max8997.c deleted file mode 100644 index cb83a7ab..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8997.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * max8997.c - mfd core driver for the Maxim 8966 and 8997 - * - * Copyright (C) 2011 Samsung Electronics - * MyungJoo Ham <myungjoo.ham@smasung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8998.c - */ - -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/pm_runtime.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/mfd/core.h> -#include <linux/mfd/max8997.h> -#include <linux/mfd/max8997-private.h> - -#define I2C_ADDR_PMIC (0xCC >> 1) -#define I2C_ADDR_MUIC (0x4A >> 1) -#define I2C_ADDR_BATTERY (0x6C >> 1) -#define I2C_ADDR_RTC (0x0C >> 1) -#define I2C_ADDR_HAPTIC (0x90 >> 1) - -static struct mfd_cell max8997_devs[] = { - { .name = "max8997-pmic", }, - { .name = "max8997-rtc", }, - { .name = "max8997-battery", }, - { .name = "max8997-haptic", }, - { .name = "max8997-muic", }, - { .name = "max8997-led", .id = 1 }, - { .name = "max8997-led", .id = 2 }, -}; - -int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8997->iolock); - ret = i2c_smbus_read_byte_data(i2c, reg); - mutex_unlock(&max8997->iolock); - if (ret < 0) - return ret; - - ret &= 0xff; - *dest = ret; - return 0; -} -EXPORT_SYMBOL_GPL(max8997_read_reg); - -int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8997->iolock); - ret = i2c_smbus_read_i2c_block_data(i2c, reg, count, buf); - mutex_unlock(&max8997->iolock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL_GPL(max8997_bulk_read); - -int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8997->iolock); - ret = i2c_smbus_write_byte_data(i2c, reg, value); - mutex_unlock(&max8997->iolock); - return ret; -} -EXPORT_SYMBOL_GPL(max8997_write_reg); - -int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8997->iolock); - ret = i2c_smbus_write_i2c_block_data(i2c, reg, count, buf); - mutex_unlock(&max8997->iolock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL_GPL(max8997_bulk_write); - -int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8997->iolock); - ret = i2c_smbus_read_byte_data(i2c, reg); - if (ret >= 0) { - u8 old_val = ret & 0xff; - u8 new_val = (val & mask) | (old_val & (~mask)); - ret = i2c_smbus_write_byte_data(i2c, reg, new_val); - } - mutex_unlock(&max8997->iolock); - return ret; -} -EXPORT_SYMBOL_GPL(max8997_update_reg); - -static int max8997_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct max8997_dev *max8997; - struct max8997_platform_data *pdata = i2c->dev.platform_data; - int ret = 0; - - max8997 = kzalloc(sizeof(struct max8997_dev), GFP_KERNEL); - if (max8997 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, max8997); - max8997->dev = &i2c->dev; - max8997->i2c = i2c; - max8997->type = id->driver_data; - max8997->irq = i2c->irq; - - if (!pdata) - goto err; - - max8997->irq_base = pdata->irq_base; - max8997->ono = pdata->ono; - - mutex_init(&max8997->iolock); - - max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); - i2c_set_clientdata(max8997->rtc, max8997); - max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); - i2c_set_clientdata(max8997->haptic, max8997); - max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); - i2c_set_clientdata(max8997->muic, max8997); - - pm_runtime_set_active(max8997->dev); - - max8997_irq_init(max8997); - - mfd_add_devices(max8997->dev, -1, max8997_devs, - ARRAY_SIZE(max8997_devs), - NULL, 0); - - /* - * TODO: enable others (flash, muic, rtc, battery, ...) and - * check the return value - */ - - if (ret < 0) - goto err_mfd; - - /* MAX8997 has a power button input. */ - device_init_wakeup(max8997->dev, pdata->wakeup); - - return ret; - -err_mfd: - mfd_remove_devices(max8997->dev); - i2c_unregister_device(max8997->muic); - i2c_unregister_device(max8997->haptic); - i2c_unregister_device(max8997->rtc); -err: - kfree(max8997); - return ret; -} - -static int max8997_i2c_remove(struct i2c_client *i2c) -{ - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - - mfd_remove_devices(max8997->dev); - i2c_unregister_device(max8997->muic); - i2c_unregister_device(max8997->haptic); - i2c_unregister_device(max8997->rtc); - kfree(max8997); - - return 0; -} - -static const struct i2c_device_id max8997_i2c_id[] = { - { "max8997", TYPE_MAX8997 }, - { "max8966", TYPE_MAX8966 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); - -u8 max8997_dumpaddr_pmic[] = { - MAX8997_REG_INT1MSK, - MAX8997_REG_INT2MSK, - MAX8997_REG_INT3MSK, - MAX8997_REG_INT4MSK, - MAX8997_REG_MAINCON1, - MAX8997_REG_MAINCON2, - MAX8997_REG_BUCKRAMP, - MAX8997_REG_BUCK1CTRL, - MAX8997_REG_BUCK1DVS1, - MAX8997_REG_BUCK1DVS2, - MAX8997_REG_BUCK1DVS3, - MAX8997_REG_BUCK1DVS4, - MAX8997_REG_BUCK1DVS5, - MAX8997_REG_BUCK1DVS6, - MAX8997_REG_BUCK1DVS7, - MAX8997_REG_BUCK1DVS8, - MAX8997_REG_BUCK2CTRL, - MAX8997_REG_BUCK2DVS1, - MAX8997_REG_BUCK2DVS2, - MAX8997_REG_BUCK2DVS3, - MAX8997_REG_BUCK2DVS4, - MAX8997_REG_BUCK2DVS5, - MAX8997_REG_BUCK2DVS6, - MAX8997_REG_BUCK2DVS7, - MAX8997_REG_BUCK2DVS8, - MAX8997_REG_BUCK3CTRL, - MAX8997_REG_BUCK3DVS, - MAX8997_REG_BUCK4CTRL, - MAX8997_REG_BUCK4DVS, - MAX8997_REG_BUCK5CTRL, - MAX8997_REG_BUCK5DVS1, - MAX8997_REG_BUCK5DVS2, - MAX8997_REG_BUCK5DVS3, - MAX8997_REG_BUCK5DVS4, - MAX8997_REG_BUCK5DVS5, - MAX8997_REG_BUCK5DVS6, - MAX8997_REG_BUCK5DVS7, - MAX8997_REG_BUCK5DVS8, - MAX8997_REG_BUCK6CTRL, - MAX8997_REG_BUCK6BPSKIPCTRL, - MAX8997_REG_BUCK7CTRL, - MAX8997_REG_BUCK7DVS, - MAX8997_REG_LDO1CTRL, - MAX8997_REG_LDO2CTRL, - MAX8997_REG_LDO3CTRL, - MAX8997_REG_LDO4CTRL, - MAX8997_REG_LDO5CTRL, - MAX8997_REG_LDO6CTRL, - MAX8997_REG_LDO7CTRL, - MAX8997_REG_LDO8CTRL, - MAX8997_REG_LDO9CTRL, - MAX8997_REG_LDO10CTRL, - MAX8997_REG_LDO11CTRL, - MAX8997_REG_LDO12CTRL, - MAX8997_REG_LDO13CTRL, - MAX8997_REG_LDO14CTRL, - MAX8997_REG_LDO15CTRL, - MAX8997_REG_LDO16CTRL, - MAX8997_REG_LDO17CTRL, - MAX8997_REG_LDO18CTRL, - MAX8997_REG_LDO21CTRL, - MAX8997_REG_MBCCTRL1, - MAX8997_REG_MBCCTRL2, - MAX8997_REG_MBCCTRL3, - MAX8997_REG_MBCCTRL4, - MAX8997_REG_MBCCTRL5, - MAX8997_REG_MBCCTRL6, - MAX8997_REG_OTPCGHCVS, - MAX8997_REG_SAFEOUTCTRL, - MAX8997_REG_LBCNFG1, - MAX8997_REG_LBCNFG2, - MAX8997_REG_BBCCTRL, - - MAX8997_REG_FLASH1_CUR, - MAX8997_REG_FLASH2_CUR, - MAX8997_REG_MOVIE_CUR, - MAX8997_REG_GSMB_CUR, - MAX8997_REG_BOOST_CNTL, - MAX8997_REG_LEN_CNTL, - MAX8997_REG_FLASH_CNTL, - MAX8997_REG_WDT_CNTL, - MAX8997_REG_MAXFLASH1, - MAX8997_REG_MAXFLASH2, - MAX8997_REG_FLASHSTATUSMASK, - - MAX8997_REG_GPIOCNTL1, - MAX8997_REG_GPIOCNTL2, - MAX8997_REG_GPIOCNTL3, - MAX8997_REG_GPIOCNTL4, - MAX8997_REG_GPIOCNTL5, - MAX8997_REG_GPIOCNTL6, - MAX8997_REG_GPIOCNTL7, - MAX8997_REG_GPIOCNTL8, - MAX8997_REG_GPIOCNTL9, - MAX8997_REG_GPIOCNTL10, - MAX8997_REG_GPIOCNTL11, - MAX8997_REG_GPIOCNTL12, - - MAX8997_REG_LDO1CONFIG, - MAX8997_REG_LDO2CONFIG, - MAX8997_REG_LDO3CONFIG, - MAX8997_REG_LDO4CONFIG, - MAX8997_REG_LDO5CONFIG, - MAX8997_REG_LDO6CONFIG, - MAX8997_REG_LDO7CONFIG, - MAX8997_REG_LDO8CONFIG, - MAX8997_REG_LDO9CONFIG, - MAX8997_REG_LDO10CONFIG, - MAX8997_REG_LDO11CONFIG, - MAX8997_REG_LDO12CONFIG, - MAX8997_REG_LDO13CONFIG, - MAX8997_REG_LDO14CONFIG, - MAX8997_REG_LDO15CONFIG, - MAX8997_REG_LDO16CONFIG, - MAX8997_REG_LDO17CONFIG, - MAX8997_REG_LDO18CONFIG, - MAX8997_REG_LDO21CONFIG, - - MAX8997_REG_DVSOKTIMER1, - MAX8997_REG_DVSOKTIMER2, - MAX8997_REG_DVSOKTIMER4, - MAX8997_REG_DVSOKTIMER5, -}; - -u8 max8997_dumpaddr_muic[] = { - MAX8997_MUIC_REG_INTMASK1, - MAX8997_MUIC_REG_INTMASK2, - MAX8997_MUIC_REG_INTMASK3, - MAX8997_MUIC_REG_CDETCTRL, - MAX8997_MUIC_REG_CONTROL1, - MAX8997_MUIC_REG_CONTROL2, - MAX8997_MUIC_REG_CONTROL3, -}; - -u8 max8997_dumpaddr_haptic[] = { - MAX8997_HAPTIC_REG_CONF1, - MAX8997_HAPTIC_REG_CONF2, - MAX8997_HAPTIC_REG_DRVCONF, - MAX8997_HAPTIC_REG_CYCLECONF1, - MAX8997_HAPTIC_REG_CYCLECONF2, - MAX8997_HAPTIC_REG_SIGCONF1, - MAX8997_HAPTIC_REG_SIGCONF2, - MAX8997_HAPTIC_REG_SIGCONF3, - MAX8997_HAPTIC_REG_SIGCONF4, - MAX8997_HAPTIC_REG_SIGDC1, - MAX8997_HAPTIC_REG_SIGDC2, - MAX8997_HAPTIC_REG_SIGPWMDC1, - MAX8997_HAPTIC_REG_SIGPWMDC2, - MAX8997_HAPTIC_REG_SIGPWMDC3, - MAX8997_HAPTIC_REG_SIGPWMDC4, -}; - -static int max8997_freeze(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int i; - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++) - max8997_read_reg(i2c, max8997_dumpaddr_pmic[i], - &max8997->reg_dump[i]); - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++) - max8997_read_reg(i2c, max8997_dumpaddr_muic[i], - &max8997->reg_dump[i + MAX8997_REG_PMIC_END]); - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++) - max8997_read_reg(i2c, max8997_dumpaddr_haptic[i], - &max8997->reg_dump[i + MAX8997_REG_PMIC_END + - MAX8997_MUIC_REG_END]); - - return 0; -} - -static int max8997_restore(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8997_dev *max8997 = i2c_get_clientdata(i2c); - int i; - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++) - max8997_write_reg(i2c, max8997_dumpaddr_pmic[i], - max8997->reg_dump[i]); - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++) - max8997_write_reg(i2c, max8997_dumpaddr_muic[i], - max8997->reg_dump[i + MAX8997_REG_PMIC_END]); - - for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++) - max8997_write_reg(i2c, max8997_dumpaddr_haptic[i], - max8997->reg_dump[i + MAX8997_REG_PMIC_END + - MAX8997_MUIC_REG_END]); - - 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 = { - .suspend = max8997_suspend, - .resume = max8997_resume, - .freeze = max8997_freeze, - .restore = max8997_restore, -}; - -static struct i2c_driver max8997_i2c_driver = { - .driver = { - .name = "max8997", - .owner = THIS_MODULE, - .pm = &max8997_pm, - }, - .probe = max8997_i2c_probe, - .remove = max8997_i2c_remove, - .id_table = max8997_i2c_id, -}; - -static int __init max8997_i2c_init(void) -{ - return i2c_add_driver(&max8997_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(max8997_i2c_init); - -static void __exit max8997_i2c_exit(void) -{ - i2c_del_driver(&max8997_i2c_driver); -} -module_exit(max8997_i2c_exit); - -MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver"); -MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/max8998-irq.c b/ANDROID_3.4.5/drivers/mfd/max8998-irq.c deleted file mode 100644 index 5919710d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8998-irq.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Interrupt controller support for MAX8998 - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mfd/max8998-private.h> - -struct max8998_irq_data { - int reg; - int mask; -}; - -static struct max8998_irq_data max8998_irqs[] = { - [MAX8998_IRQ_DCINF] = { - .reg = 1, - .mask = MAX8998_IRQ_DCINF_MASK, - }, - [MAX8998_IRQ_DCINR] = { - .reg = 1, - .mask = MAX8998_IRQ_DCINR_MASK, - }, - [MAX8998_IRQ_JIGF] = { - .reg = 1, - .mask = MAX8998_IRQ_JIGF_MASK, - }, - [MAX8998_IRQ_JIGR] = { - .reg = 1, - .mask = MAX8998_IRQ_JIGR_MASK, - }, - [MAX8998_IRQ_PWRONF] = { - .reg = 1, - .mask = MAX8998_IRQ_PWRONF_MASK, - }, - [MAX8998_IRQ_PWRONR] = { - .reg = 1, - .mask = MAX8998_IRQ_PWRONR_MASK, - }, - [MAX8998_IRQ_WTSREVNT] = { - .reg = 2, - .mask = MAX8998_IRQ_WTSREVNT_MASK, - }, - [MAX8998_IRQ_SMPLEVNT] = { - .reg = 2, - .mask = MAX8998_IRQ_SMPLEVNT_MASK, - }, - [MAX8998_IRQ_ALARM1] = { - .reg = 2, - .mask = MAX8998_IRQ_ALARM1_MASK, - }, - [MAX8998_IRQ_ALARM0] = { - .reg = 2, - .mask = MAX8998_IRQ_ALARM0_MASK, - }, - [MAX8998_IRQ_ONKEY1S] = { - .reg = 3, - .mask = MAX8998_IRQ_ONKEY1S_MASK, - }, - [MAX8998_IRQ_TOPOFFR] = { - .reg = 3, - .mask = MAX8998_IRQ_TOPOFFR_MASK, - }, - [MAX8998_IRQ_DCINOVPR] = { - .reg = 3, - .mask = MAX8998_IRQ_DCINOVPR_MASK, - }, - [MAX8998_IRQ_CHGRSTF] = { - .reg = 3, - .mask = MAX8998_IRQ_CHGRSTF_MASK, - }, - [MAX8998_IRQ_DONER] = { - .reg = 3, - .mask = MAX8998_IRQ_DONER_MASK, - }, - [MAX8998_IRQ_CHGFAULT] = { - .reg = 3, - .mask = MAX8998_IRQ_CHGFAULT_MASK, - }, - [MAX8998_IRQ_LOBAT1] = { - .reg = 4, - .mask = MAX8998_IRQ_LOBAT1_MASK, - }, - [MAX8998_IRQ_LOBAT2] = { - .reg = 4, - .mask = MAX8998_IRQ_LOBAT2_MASK, - }, -}; - -static inline struct max8998_irq_data * -irq_to_max8998_irq(struct max8998_dev *max8998, int irq) -{ - return &max8998_irqs[irq - max8998->irq_base]; -} - -static void max8998_irq_lock(struct irq_data *data) -{ - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - - mutex_lock(&max8998->irqlock); -} - -static void max8998_irq_sync_unlock(struct irq_data *data) -{ - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { - /* - * If there's been a change in the mask write it back - * to the hardware. - */ - if (max8998->irq_masks_cur[i] != max8998->irq_masks_cache[i]) { - max8998->irq_masks_cache[i] = max8998->irq_masks_cur[i]; - max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, - max8998->irq_masks_cur[i]); - } - } - - mutex_unlock(&max8998->irqlock); -} - -static void max8998_irq_unmask(struct irq_data *data) -{ - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, - data->irq); - - max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; -} - -static void max8998_irq_mask(struct irq_data *data) -{ - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, - data->irq); - - max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; -} - -static struct irq_chip max8998_irq_chip = { - .name = "max8998", - .irq_bus_lock = max8998_irq_lock, - .irq_bus_sync_unlock = max8998_irq_sync_unlock, - .irq_mask = max8998_irq_mask, - .irq_unmask = max8998_irq_unmask, -}; - -static irqreturn_t max8998_irq_thread(int irq, void *data) -{ - struct max8998_dev *max8998 = data; - u8 irq_reg[MAX8998_NUM_IRQ_REGS]; - int ret; - int i; - - ret = max8998_bulk_read(max8998->i2c, MAX8998_REG_IRQ1, - MAX8998_NUM_IRQ_REGS, irq_reg); - if (ret < 0) { - dev_err(max8998->dev, "Failed to read interrupt register: %d\n", - ret); - return IRQ_NONE; - } - - /* Apply masking */ - for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) - irq_reg[i] &= ~max8998->irq_masks_cur[i]; - - /* Report */ - for (i = 0; i < MAX8998_IRQ_NR; i++) { - if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) - handle_nested_irq(max8998->irq_base + i); - } - - return IRQ_HANDLED; -} - -int max8998_irq_resume(struct max8998_dev *max8998) -{ - if (max8998->irq && max8998->irq_base) - max8998_irq_thread(max8998->irq_base, max8998); - return 0; -} - -int max8998_irq_init(struct max8998_dev *max8998) -{ - int i; - int cur_irq; - int ret; - - if (!max8998->irq) { - dev_warn(max8998->dev, - "No interrupt specified, no interrupts\n"); - max8998->irq_base = 0; - return 0; - } - - if (!max8998->irq_base) { - dev_err(max8998->dev, - "No interrupt base specified, no interrupts\n"); - return 0; - } - - mutex_init(&max8998->irqlock); - - /* Mask the individual interrupt sources */ - for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) { - max8998->irq_masks_cur[i] = 0xff; - max8998->irq_masks_cache[i] = 0xff; - max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 0xff); - } - - max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff); - max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff); - - /* register with genirq */ - for (i = 0; i < MAX8998_IRQ_NR; i++) { - cur_irq = i + max8998->irq_base; - irq_set_chip_data(cur_irq, max8998); - irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "max8998-irq", max8998); - if (ret) { - dev_err(max8998->dev, "Failed to request IRQ %d: %d\n", - max8998->irq, ret); - return ret; - } - - if (!max8998->ono) - return 0; - - ret = request_threaded_irq(max8998->ono, NULL, max8998_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "max8998-ono", max8998); - if (ret) - dev_err(max8998->dev, "Failed to request IRQ %d: %d\n", - max8998->ono, ret); - - return 0; -} - -void max8998_irq_exit(struct max8998_dev *max8998) -{ - if (max8998->ono) - free_irq(max8998->ono, max8998); - - if (max8998->irq) - free_irq(max8998->irq, max8998); -} diff --git a/ANDROID_3.4.5/drivers/mfd/max8998.c b/ANDROID_3.4.5/drivers/mfd/max8998.c deleted file mode 100644 index 6ef56d28..00000000 --- a/ANDROID_3.4.5/drivers/mfd/max8998.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * max8998.c - mfd core driver for the Maxim 8998 - * - * Copyright (C) 2009-2010 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * Marek Szyprowski <m.szyprowski@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/pm_runtime.h> -#include <linux/mutex.h> -#include <linux/mfd/core.h> -#include <linux/mfd/max8998.h> -#include <linux/mfd/max8998-private.h> - -#define RTC_I2C_ADDR (0x0c >> 1) - -static struct mfd_cell max8998_devs[] = { - { - .name = "max8998-pmic", - }, { - .name = "max8998-rtc", - }, { - .name = "max8998-battery", - }, -}; - -static struct mfd_cell lp3974_devs[] = { - { - .name = "lp3974-pmic", - }, { - .name = "lp3974-rtc", - }, -}; - -int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8998->iolock); - ret = i2c_smbus_read_byte_data(i2c, reg); - mutex_unlock(&max8998->iolock); - if (ret < 0) - return ret; - - ret &= 0xff; - *dest = ret; - return 0; -} -EXPORT_SYMBOL(max8998_read_reg); - -int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8998->iolock); - ret = i2c_smbus_read_i2c_block_data(i2c, reg, count, buf); - mutex_unlock(&max8998->iolock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(max8998_bulk_read); - -int max8998_write_reg(struct i2c_client *i2c, u8 reg, u8 value) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8998->iolock); - ret = i2c_smbus_write_byte_data(i2c, reg, value); - mutex_unlock(&max8998->iolock); - return ret; -} -EXPORT_SYMBOL(max8998_write_reg); - -int max8998_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8998->iolock); - ret = i2c_smbus_write_i2c_block_data(i2c, reg, count, buf); - mutex_unlock(&max8998->iolock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(max8998_bulk_write); - -int max8998_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - int ret; - - mutex_lock(&max8998->iolock); - ret = i2c_smbus_read_byte_data(i2c, reg); - if (ret >= 0) { - u8 old_val = ret & 0xff; - u8 new_val = (val & mask) | (old_val & (~mask)); - ret = i2c_smbus_write_byte_data(i2c, reg, new_val); - } - mutex_unlock(&max8998->iolock); - return ret; -} -EXPORT_SYMBOL(max8998_update_reg); - -static int max8998_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct max8998_platform_data *pdata = i2c->dev.platform_data; - struct max8998_dev *max8998; - int ret = 0; - - max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL); - if (max8998 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, max8998); - max8998->dev = &i2c->dev; - max8998->i2c = i2c; - max8998->irq = i2c->irq; - max8998->type = id->driver_data; - if (pdata) { - max8998->ono = pdata->ono; - max8998->irq_base = pdata->irq_base; - max8998->wakeup = pdata->wakeup; - } - mutex_init(&max8998->iolock); - - max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); - i2c_set_clientdata(max8998->rtc, max8998); - - max8998_irq_init(max8998); - - pm_runtime_set_active(max8998->dev); - - switch (id->driver_data) { - case TYPE_LP3974: - ret = mfd_add_devices(max8998->dev, -1, - lp3974_devs, ARRAY_SIZE(lp3974_devs), - NULL, 0); - break; - case TYPE_MAX8998: - ret = mfd_add_devices(max8998->dev, -1, - max8998_devs, ARRAY_SIZE(max8998_devs), - NULL, 0); - break; - default: - ret = -EINVAL; - } - - if (ret < 0) - goto err; - - device_init_wakeup(max8998->dev, max8998->wakeup); - - return ret; - -err: - mfd_remove_devices(max8998->dev); - max8998_irq_exit(max8998); - i2c_unregister_device(max8998->rtc); - kfree(max8998); - return ret; -} - -static int max8998_i2c_remove(struct i2c_client *i2c) -{ - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - - mfd_remove_devices(max8998->dev); - max8998_irq_exit(max8998); - i2c_unregister_device(max8998->rtc); - kfree(max8998); - - return 0; -} - -static const struct i2c_device_id max8998_i2c_id[] = { - { "max8998", TYPE_MAX8998 }, - { "lp3974", TYPE_LP3974}, - { } -}; -MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); - -static int max8998_suspend(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - - if (device_may_wakeup(dev)) - irq_set_irq_wake(max8998->irq, 1); - return 0; -} - -static int max8998_resume(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - - if (device_may_wakeup(dev)) - irq_set_irq_wake(max8998->irq, 0); - /* - * In LP3974, if IRQ registers are not "read & clear" - * when it's set during sleep, the interrupt becomes - * disabled. - */ - return max8998_irq_resume(i2c_get_clientdata(i2c)); -} - -struct max8998_reg_dump { - u8 addr; - u8 val; -}; -#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } -static struct max8998_reg_dump max8998_dump[] = { - SAVE_ITEM(MAX8998_REG_IRQM1), - SAVE_ITEM(MAX8998_REG_IRQM2), - SAVE_ITEM(MAX8998_REG_IRQM3), - SAVE_ITEM(MAX8998_REG_IRQM4), - SAVE_ITEM(MAX8998_REG_STATUSM1), - SAVE_ITEM(MAX8998_REG_STATUSM2), - SAVE_ITEM(MAX8998_REG_CHGR1), - SAVE_ITEM(MAX8998_REG_CHGR2), - SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), - SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), - SAVE_ITEM(MAX8998_REG_BUCK_ACTIVE_DISCHARGE3), - SAVE_ITEM(MAX8998_REG_ONOFF1), - SAVE_ITEM(MAX8998_REG_ONOFF2), - SAVE_ITEM(MAX8998_REG_ONOFF3), - SAVE_ITEM(MAX8998_REG_ONOFF4), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE1), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE2), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE3), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE4), - SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE1), - SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE2), - SAVE_ITEM(MAX8998_REG_LDO2_LDO3), - SAVE_ITEM(MAX8998_REG_LDO4), - SAVE_ITEM(MAX8998_REG_LDO5), - SAVE_ITEM(MAX8998_REG_LDO6), - SAVE_ITEM(MAX8998_REG_LDO7), - SAVE_ITEM(MAX8998_REG_LDO8_LDO9), - SAVE_ITEM(MAX8998_REG_LDO10_LDO11), - SAVE_ITEM(MAX8998_REG_LDO12), - SAVE_ITEM(MAX8998_REG_LDO13), - SAVE_ITEM(MAX8998_REG_LDO14), - SAVE_ITEM(MAX8998_REG_LDO15), - SAVE_ITEM(MAX8998_REG_LDO16), - SAVE_ITEM(MAX8998_REG_LDO17), - SAVE_ITEM(MAX8998_REG_BKCHR), - SAVE_ITEM(MAX8998_REG_LBCNFG1), - SAVE_ITEM(MAX8998_REG_LBCNFG2), -}; -/* Save registers before hibernation */ -static int max8998_freeze(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - int i; - - for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) - max8998_read_reg(i2c, max8998_dump[i].addr, - &max8998_dump[i].val); - - return 0; -} - -/* Restore registers after hibernation */ -static int max8998_restore(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - int i; - - for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) - max8998_write_reg(i2c, max8998_dump[i].addr, - max8998_dump[i].val); - - return 0; -} - -static const struct dev_pm_ops max8998_pm = { - .suspend = max8998_suspend, - .resume = max8998_resume, - .freeze = max8998_freeze, - .restore = max8998_restore, -}; - -static struct i2c_driver max8998_i2c_driver = { - .driver = { - .name = "max8998", - .owner = THIS_MODULE, - .pm = &max8998_pm, - }, - .probe = max8998_i2c_probe, - .remove = max8998_i2c_remove, - .id_table = max8998_i2c_id, -}; - -static int __init max8998_i2c_init(void) -{ - return i2c_add_driver(&max8998_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(max8998_i2c_init); - -static void __exit max8998_i2c_exit(void) -{ - i2c_del_driver(&max8998_i2c_driver); -} -module_exit(max8998_i2c_exit); - -MODULE_DESCRIPTION("MAXIM 8998 multi-function core driver"); -MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/mc13xxx-core.c b/ANDROID_3.4.5/drivers/mfd/mc13xxx-core.c deleted file mode 100644 index 9fd4f63c..00000000 --- a/ANDROID_3.4.5/drivers/mfd/mc13xxx-core.c +++ /dev/null @@ -1,879 +0,0 @@ -/* - * Copyright 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - * - * loosely based on an earlier driver that has - * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by the - * Free Software Foundation. - */ - -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mutex.h> -#include <linux/interrupt.h> -#include <linux/spi/spi.h> -#include <linux/mfd/core.h> -#include <linux/mfd/mc13xxx.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/of_gpio.h> - -struct mc13xxx { - struct spi_device *spidev; - struct mutex lock; - int irq; - int flags; - - irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; - void *irqdata[MC13XXX_NUM_IRQ]; - - int adcflags; -}; - -#define MC13XXX_IRQSTAT0 0 -#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) -#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1) -#define MC13XXX_IRQSTAT0_TSI (1 << 2) -#define MC13783_IRQSTAT0_WHIGHI (1 << 3) -#define MC13783_IRQSTAT0_WLOWI (1 << 4) -#define MC13XXX_IRQSTAT0_CHGDETI (1 << 6) -#define MC13783_IRQSTAT0_CHGOVI (1 << 7) -#define MC13XXX_IRQSTAT0_CHGREVI (1 << 8) -#define MC13XXX_IRQSTAT0_CHGSHORTI (1 << 9) -#define MC13XXX_IRQSTAT0_CCCVI (1 << 10) -#define MC13XXX_IRQSTAT0_CHGCURRI (1 << 11) -#define MC13XXX_IRQSTAT0_BPONI (1 << 12) -#define MC13XXX_IRQSTAT0_LOBATLI (1 << 13) -#define MC13XXX_IRQSTAT0_LOBATHI (1 << 14) -#define MC13783_IRQSTAT0_UDPI (1 << 15) -#define MC13783_IRQSTAT0_USBI (1 << 16) -#define MC13783_IRQSTAT0_IDI (1 << 19) -#define MC13783_IRQSTAT0_SE1I (1 << 21) -#define MC13783_IRQSTAT0_CKDETI (1 << 22) -#define MC13783_IRQSTAT0_UDMI (1 << 23) - -#define MC13XXX_IRQMASK0 1 -#define MC13XXX_IRQMASK0_ADCDONEM MC13XXX_IRQSTAT0_ADCDONEI -#define MC13XXX_IRQMASK0_ADCBISDONEM MC13XXX_IRQSTAT0_ADCBISDONEI -#define MC13XXX_IRQMASK0_TSM MC13XXX_IRQSTAT0_TSI -#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI -#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI -#define MC13XXX_IRQMASK0_CHGDETM MC13XXX_IRQSTAT0_CHGDETI -#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI -#define MC13XXX_IRQMASK0_CHGREVM MC13XXX_IRQSTAT0_CHGREVI -#define MC13XXX_IRQMASK0_CHGSHORTM MC13XXX_IRQSTAT0_CHGSHORTI -#define MC13XXX_IRQMASK0_CCCVM MC13XXX_IRQSTAT0_CCCVI -#define MC13XXX_IRQMASK0_CHGCURRM MC13XXX_IRQSTAT0_CHGCURRI -#define MC13XXX_IRQMASK0_BPONM MC13XXX_IRQSTAT0_BPONI -#define MC13XXX_IRQMASK0_LOBATLM MC13XXX_IRQSTAT0_LOBATLI -#define MC13XXX_IRQMASK0_LOBATHM MC13XXX_IRQSTAT0_LOBATHI -#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI -#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI -#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI -#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I -#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI -#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI - -#define MC13XXX_IRQSTAT1 3 -#define MC13XXX_IRQSTAT1_1HZI (1 << 0) -#define MC13XXX_IRQSTAT1_TODAI (1 << 1) -#define MC13783_IRQSTAT1_ONOFD1I (1 << 3) -#define MC13783_IRQSTAT1_ONOFD2I (1 << 4) -#define MC13783_IRQSTAT1_ONOFD3I (1 << 5) -#define MC13XXX_IRQSTAT1_SYSRSTI (1 << 6) -#define MC13XXX_IRQSTAT1_RTCRSTI (1 << 7) -#define MC13XXX_IRQSTAT1_PCI (1 << 8) -#define MC13XXX_IRQSTAT1_WARMI (1 << 9) -#define MC13XXX_IRQSTAT1_MEMHLDI (1 << 10) -#define MC13783_IRQSTAT1_PWRRDYI (1 << 11) -#define MC13XXX_IRQSTAT1_THWARNLI (1 << 12) -#define MC13XXX_IRQSTAT1_THWARNHI (1 << 13) -#define MC13XXX_IRQSTAT1_CLKI (1 << 14) -#define MC13783_IRQSTAT1_SEMAFI (1 << 15) -#define MC13783_IRQSTAT1_MC2BI (1 << 17) -#define MC13783_IRQSTAT1_HSDETI (1 << 18) -#define MC13783_IRQSTAT1_HSLI (1 << 19) -#define MC13783_IRQSTAT1_ALSPTHI (1 << 20) -#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21) - -#define MC13XXX_IRQMASK1 4 -#define MC13XXX_IRQMASK1_1HZM MC13XXX_IRQSTAT1_1HZI -#define MC13XXX_IRQMASK1_TODAM MC13XXX_IRQSTAT1_TODAI -#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I -#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I -#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I -#define MC13XXX_IRQMASK1_SYSRSTM MC13XXX_IRQSTAT1_SYSRSTI -#define MC13XXX_IRQMASK1_RTCRSTM MC13XXX_IRQSTAT1_RTCRSTI -#define MC13XXX_IRQMASK1_PCM MC13XXX_IRQSTAT1_PCI -#define MC13XXX_IRQMASK1_WARMM MC13XXX_IRQSTAT1_WARMI -#define MC13XXX_IRQMASK1_MEMHLDM MC13XXX_IRQSTAT1_MEMHLDI -#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI -#define MC13XXX_IRQMASK1_THWARNLM MC13XXX_IRQSTAT1_THWARNLI -#define MC13XXX_IRQMASK1_THWARNHM MC13XXX_IRQSTAT1_THWARNHI -#define MC13XXX_IRQMASK1_CLKM MC13XXX_IRQSTAT1_CLKI -#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI -#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI -#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI -#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI -#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI -#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI - -#define MC13XXX_REVISION 7 -#define MC13XXX_REVISION_REVMETAL (0x07 << 0) -#define MC13XXX_REVISION_REVFULL (0x03 << 3) -#define MC13XXX_REVISION_ICID (0x07 << 6) -#define MC13XXX_REVISION_FIN (0x03 << 9) -#define MC13XXX_REVISION_FAB (0x03 << 11) -#define MC13XXX_REVISION_ICIDCODE (0x3f << 13) - -#define MC13XXX_ADC1 44 -#define MC13XXX_ADC1_ADEN (1 << 0) -#define MC13XXX_ADC1_RAND (1 << 1) -#define MC13XXX_ADC1_ADSEL (1 << 3) -#define MC13XXX_ADC1_ASC (1 << 20) -#define MC13XXX_ADC1_ADTRIGIGN (1 << 21) - -#define MC13XXX_ADC2 45 - -#define MC13XXX_NUMREGS 0x3f - -void mc13xxx_lock(struct mc13xxx *mc13xxx) -{ - if (!mutex_trylock(&mc13xxx->lock)) { - dev_dbg(&mc13xxx->spidev->dev, "wait for %s from %pf\n", - __func__, __builtin_return_address(0)); - - mutex_lock(&mc13xxx->lock); - } - dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", - __func__, __builtin_return_address(0)); -} -EXPORT_SYMBOL(mc13xxx_lock); - -void mc13xxx_unlock(struct mc13xxx *mc13xxx) -{ - dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", - __func__, __builtin_return_address(0)); - mutex_unlock(&mc13xxx->lock); -} -EXPORT_SYMBOL(mc13xxx_unlock); - -#define MC13XXX_REGOFFSET_SHIFT 25 -int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) -{ - struct spi_transfer t; - struct spi_message m; - int ret; - - BUG_ON(!mutex_is_locked(&mc13xxx->lock)); - - if (offset > MC13XXX_NUMREGS) - return -EINVAL; - - *val = offset << MC13XXX_REGOFFSET_SHIFT; - - memset(&t, 0, sizeof(t)); - - t.tx_buf = val; - t.rx_buf = val; - t.len = sizeof(u32); - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - ret = spi_sync(mc13xxx->spidev, &m); - - /* error in message.status implies error return from spi_sync */ - BUG_ON(!ret && m.status); - - if (ret) - return ret; - - *val &= 0xffffff; - - dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val); - - return 0; -} -EXPORT_SYMBOL(mc13xxx_reg_read); - -int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) -{ - u32 buf; - struct spi_transfer t; - struct spi_message m; - int ret; - - BUG_ON(!mutex_is_locked(&mc13xxx->lock)); - - dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val); - - if (offset > MC13XXX_NUMREGS || val > 0xffffff) - return -EINVAL; - - buf = 1 << 31 | offset << MC13XXX_REGOFFSET_SHIFT | val; - - memset(&t, 0, sizeof(t)); - - t.tx_buf = &buf; - t.rx_buf = &buf; - t.len = sizeof(u32); - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - ret = spi_sync(mc13xxx->spidev, &m); - - BUG_ON(!ret && m.status); - - if (ret) - return ret; - - return 0; -} -EXPORT_SYMBOL(mc13xxx_reg_write); - -int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, - u32 mask, u32 val) -{ - int ret; - u32 valread; - - BUG_ON(val & ~mask); - - ret = mc13xxx_reg_read(mc13xxx, offset, &valread); - if (ret) - return ret; - - valread = (valread & ~mask) | val; - - return mc13xxx_reg_write(mc13xxx, offset, valread); -} -EXPORT_SYMBOL(mc13xxx_reg_rmw); - -int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq) -{ - int ret; - unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); - u32 mask; - - if (irq < 0 || irq >= MC13XXX_NUM_IRQ) - return -EINVAL; - - ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); - if (ret) - return ret; - - if (mask & irqbit) - /* already masked */ - return 0; - - return mc13xxx_reg_write(mc13xxx, offmask, mask | irqbit); -} -EXPORT_SYMBOL(mc13xxx_irq_mask); - -int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq) -{ - int ret; - unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); - u32 mask; - - if (irq < 0 || irq >= MC13XXX_NUM_IRQ) - return -EINVAL; - - ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); - if (ret) - return ret; - - if (!(mask & irqbit)) - /* already unmasked */ - return 0; - - return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit); -} -EXPORT_SYMBOL(mc13xxx_irq_unmask); - -int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq, - int *enabled, int *pending) -{ - int ret; - unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; - unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); - - if (irq < 0 || irq >= MC13XXX_NUM_IRQ) - return -EINVAL; - - if (enabled) { - u32 mask; - - ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); - if (ret) - return ret; - - *enabled = mask & irqbit; - } - - if (pending) { - u32 stat; - - ret = mc13xxx_reg_read(mc13xxx, offstat, &stat); - if (ret) - return ret; - - *pending = stat & irqbit; - } - - return 0; -} -EXPORT_SYMBOL(mc13xxx_irq_status); - -int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq) -{ - unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; - unsigned int val = 1 << (irq < 24 ? irq : irq - 24); - - BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ); - - return mc13xxx_reg_write(mc13xxx, offstat, val); -} -EXPORT_SYMBOL(mc13xxx_irq_ack); - -int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq, - irq_handler_t handler, const char *name, void *dev) -{ - BUG_ON(!mutex_is_locked(&mc13xxx->lock)); - BUG_ON(!handler); - - if (irq < 0 || irq >= MC13XXX_NUM_IRQ) - return -EINVAL; - - if (mc13xxx->irqhandler[irq]) - return -EBUSY; - - mc13xxx->irqhandler[irq] = handler; - mc13xxx->irqdata[irq] = dev; - - return 0; -} -EXPORT_SYMBOL(mc13xxx_irq_request_nounmask); - -int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, - irq_handler_t handler, const char *name, void *dev) -{ - int ret; - - ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev); - if (ret) - return ret; - - ret = mc13xxx_irq_unmask(mc13xxx, irq); - if (ret) { - mc13xxx->irqhandler[irq] = NULL; - mc13xxx->irqdata[irq] = NULL; - return ret; - } - - return 0; -} -EXPORT_SYMBOL(mc13xxx_irq_request); - -int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev) -{ - int ret; - BUG_ON(!mutex_is_locked(&mc13xxx->lock)); - - if (irq < 0 || irq >= MC13XXX_NUM_IRQ || !mc13xxx->irqhandler[irq] || - mc13xxx->irqdata[irq] != dev) - return -EINVAL; - - ret = mc13xxx_irq_mask(mc13xxx, irq); - if (ret) - return ret; - - mc13xxx->irqhandler[irq] = NULL; - mc13xxx->irqdata[irq] = NULL; - - return 0; -} -EXPORT_SYMBOL(mc13xxx_irq_free); - -static inline irqreturn_t mc13xxx_irqhandler(struct mc13xxx *mc13xxx, int irq) -{ - return mc13xxx->irqhandler[irq](irq, mc13xxx->irqdata[irq]); -} - -/* - * returns: number of handled irqs or negative error - * locking: holds mc13xxx->lock - */ -static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx, - unsigned int offstat, unsigned int offmask, int baseirq) -{ - u32 stat, mask; - int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat); - int num_handled = 0; - - if (ret) - return ret; - - ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); - if (ret) - return ret; - - while (stat & ~mask) { - int irq = __ffs(stat & ~mask); - - stat &= ~(1 << irq); - - if (likely(mc13xxx->irqhandler[baseirq + irq])) { - irqreturn_t handled; - - handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq); - if (handled == IRQ_HANDLED) - num_handled++; - } else { - dev_err(&mc13xxx->spidev->dev, - "BUG: irq %u but no handler\n", - baseirq + irq); - - mask |= 1 << irq; - - ret = mc13xxx_reg_write(mc13xxx, offmask, mask); - } - } - - return num_handled; -} - -static irqreturn_t mc13xxx_irq_thread(int irq, void *data) -{ - struct mc13xxx *mc13xxx = data; - irqreturn_t ret; - int handled = 0; - - mc13xxx_lock(mc13xxx); - - ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT0, - MC13XXX_IRQMASK0, 0); - if (ret > 0) - handled = 1; - - ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT1, - MC13XXX_IRQMASK1, 24); - if (ret > 0) - handled = 1; - - mc13xxx_unlock(mc13xxx); - - return IRQ_RETVAL(handled); -} - -enum mc13xxx_id { - MC13XXX_ID_MC13783, - MC13XXX_ID_MC13892, - MC13XXX_ID_INVALID, -}; - -static const char *mc13xxx_chipname[] = { - [MC13XXX_ID_MC13783] = "mc13783", - [MC13XXX_ID_MC13892] = "mc13892", -}; - -#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) -static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) -{ - u32 icid; - u32 revision; - const char *name; - int ret; - - ret = mc13xxx_reg_read(mc13xxx, 46, &icid); - if (ret) - return ret; - - icid = (icid >> 6) & 0x7; - - switch (icid) { - case 2: - *id = MC13XXX_ID_MC13783; - name = "mc13783"; - break; - case 7: - *id = MC13XXX_ID_MC13892; - name = "mc13892"; - break; - default: - *id = MC13XXX_ID_INVALID; - break; - } - - if (*id == MC13XXX_ID_MC13783 || *id == MC13XXX_ID_MC13892) { - ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); - if (ret) - return ret; - - dev_info(&mc13xxx->spidev->dev, "%s: rev: %d.%d, " - "fin: %d, fab: %d, icid: %d/%d\n", - mc13xxx_chipname[*id], - maskval(revision, MC13XXX_REVISION_REVFULL), - maskval(revision, MC13XXX_REVISION_REVMETAL), - maskval(revision, MC13XXX_REVISION_FIN), - maskval(revision, MC13XXX_REVISION_FAB), - maskval(revision, MC13XXX_REVISION_ICID), - maskval(revision, MC13XXX_REVISION_ICIDCODE)); - } - - if (*id != MC13XXX_ID_INVALID) { - const struct spi_device_id *devid = - spi_get_device_id(mc13xxx->spidev); - if (!devid || devid->driver_data != *id) - dev_warn(&mc13xxx->spidev->dev, "device id doesn't " - "match auto detection!\n"); - } - - return 0; -} - -static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) -{ - const struct spi_device_id *devid = - spi_get_device_id(mc13xxx->spidev); - - if (!devid) - return NULL; - - return mc13xxx_chipname[devid->driver_data]; -} - -int mc13xxx_get_flags(struct mc13xxx *mc13xxx) -{ - return mc13xxx->flags; -} -EXPORT_SYMBOL(mc13xxx_get_flags); - -#define MC13XXX_ADC1_CHAN0_SHIFT 5 -#define MC13XXX_ADC1_CHAN1_SHIFT 8 -#define MC13783_ADC1_ATO_SHIFT 11 -#define MC13783_ADC1_ATOX (1 << 19) - -struct mc13xxx_adcdone_data { - struct mc13xxx *mc13xxx; - struct completion done; -}; - -static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data) -{ - struct mc13xxx_adcdone_data *adcdone_data = data; - - mc13xxx_irq_ack(adcdone_data->mc13xxx, irq); - - complete_all(&adcdone_data->done); - - return IRQ_HANDLED; -} - -#define MC13XXX_ADC_WORKING (1 << 0) - -int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, - unsigned int channel, u8 ato, bool atox, - unsigned int *sample) -{ - u32 adc0, adc1, old_adc0; - int i, ret; - struct mc13xxx_adcdone_data adcdone_data = { - .mc13xxx = mc13xxx, - }; - init_completion(&adcdone_data.done); - - dev_dbg(&mc13xxx->spidev->dev, "%s\n", __func__); - - mc13xxx_lock(mc13xxx); - - if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) { - ret = -EBUSY; - goto out; - } - - mc13xxx->adcflags |= MC13XXX_ADC_WORKING; - - mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0); - - adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2; - adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC; - - if (channel > 7) - adc1 |= MC13XXX_ADC1_ADSEL; - - switch (mode) { - case MC13XXX_ADC_MODE_TS: - adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 | - MC13XXX_ADC0_TSMOD1; - adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; - break; - - case MC13XXX_ADC_MODE_SINGLE_CHAN: - adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; - adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; - adc1 |= MC13XXX_ADC1_RAND; - break; - - case MC13XXX_ADC_MODE_MULT_CHAN: - adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; - adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; - break; - - default: - mc13xxx_unlock(mc13xxx); - return -EINVAL; - } - - adc1 |= ato << MC13783_ADC1_ATO_SHIFT; - if (atox) - adc1 |= MC13783_ADC1_ATOX; - dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__); - mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, - mc13xxx_handler_adcdone, __func__, &adcdone_data); - mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); - - mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); - mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); - - mc13xxx_unlock(mc13xxx); - - ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ); - - if (!ret) - ret = -ETIMEDOUT; - - mc13xxx_lock(mc13xxx); - - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_ADCDONE, &adcdone_data); - - if (ret > 0) - for (i = 0; i < 4; ++i) { - ret = mc13xxx_reg_read(mc13xxx, - MC13XXX_ADC2, &sample[i]); - if (ret) - break; - } - - if (mode == MC13XXX_ADC_MODE_TS) - /* restore TSMOD */ - mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, old_adc0); - - mc13xxx->adcflags &= ~MC13XXX_ADC_WORKING; -out: - mc13xxx_unlock(mc13xxx); - - return ret; -} -EXPORT_SYMBOL_GPL(mc13xxx_adc_do_conversion); - -static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, - const char *format, void *pdata, size_t pdata_size) -{ - char buf[30]; - const char *name = mc13xxx_get_chipname(mc13xxx); - - struct mfd_cell cell = { - .platform_data = pdata, - .pdata_size = pdata_size, - }; - - /* there is no asnprintf in the kernel :-( */ - if (snprintf(buf, sizeof(buf), format, name) > sizeof(buf)) - return -E2BIG; - - cell.name = kmemdup(buf, strlen(buf) + 1, GFP_KERNEL); - if (!cell.name) - return -ENOMEM; - - return mfd_add_devices(&mc13xxx->spidev->dev, -1, &cell, 1, NULL, 0); -} - -static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) -{ - return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); -} - -#ifdef CONFIG_OF -static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) -{ - struct device_node *np = mc13xxx->spidev->dev.of_node; - - if (!np) - return -ENODEV; - - if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL)) - mc13xxx->flags |= MC13XXX_USE_ADC; - - if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL)) - mc13xxx->flags |= MC13XXX_USE_CODEC; - - if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL)) - mc13xxx->flags |= MC13XXX_USE_RTC; - - if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL)) - mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN; - - return 0; -} -#else -static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) -{ - return -ENODEV; -} -#endif - -static const struct spi_device_id mc13xxx_device_id[] = { - { - .name = "mc13783", - .driver_data = MC13XXX_ID_MC13783, - }, { - .name = "mc13892", - .driver_data = MC13XXX_ID_MC13892, - }, { - /* sentinel */ - } -}; -MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); - -static const struct of_device_id mc13xxx_dt_ids[] = { - { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, - { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); - -static int mc13xxx_probe(struct spi_device *spi) -{ - const struct of_device_id *of_id; - struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); - struct mc13xxx *mc13xxx; - struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); - enum mc13xxx_id id; - int ret; - - of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); - if (of_id) - sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; - - mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); - if (!mc13xxx) - return -ENOMEM; - - dev_set_drvdata(&spi->dev, mc13xxx); - spi->mode = SPI_MODE_0 | SPI_CS_HIGH; - spi->bits_per_word = 32; - spi_setup(spi); - - mc13xxx->spidev = spi; - - mutex_init(&mc13xxx->lock); - mc13xxx_lock(mc13xxx); - - ret = mc13xxx_identify(mc13xxx, &id); - if (ret || id == MC13XXX_ID_INVALID) - goto err_revision; - - /* mask all irqs */ - ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff); - if (ret) - goto err_mask; - - ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff); - if (ret) - goto err_mask; - - ret = request_threaded_irq(spi->irq, NULL, mc13xxx_irq_thread, - IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); - - if (ret) { -err_mask: -err_revision: - mc13xxx_unlock(mc13xxx); - dev_set_drvdata(&spi->dev, NULL); - kfree(mc13xxx); - return ret; - } - - mc13xxx_unlock(mc13xxx); - - if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) - mc13xxx->flags = pdata->flags; - - if (mc13xxx->flags & MC13XXX_USE_ADC) - mc13xxx_add_subdevice(mc13xxx, "%s-adc"); - - if (mc13xxx->flags & MC13XXX_USE_CODEC) - mc13xxx_add_subdevice(mc13xxx, "%s-codec"); - - if (mc13xxx->flags & MC13XXX_USE_RTC) - mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); - - if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) - mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", - &pdata->touch, sizeof(pdata->touch)); - - if (pdata) { - mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", - &pdata->regulators, sizeof(pdata->regulators)); - mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", - pdata->leds, sizeof(*pdata->leds)); - mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", - pdata->buttons, sizeof(*pdata->buttons)); - } else { - mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); - mc13xxx_add_subdevice(mc13xxx, "%s-led"); - mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); - } - - return 0; -} - -static int __devexit mc13xxx_remove(struct spi_device *spi) -{ - struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); - - free_irq(mc13xxx->spidev->irq, mc13xxx); - - mfd_remove_devices(&spi->dev); - - kfree(mc13xxx); - - return 0; -} - -static struct spi_driver mc13xxx_driver = { - .id_table = mc13xxx_device_id, - .driver = { - .name = "mc13xxx", - .owner = THIS_MODULE, - .of_match_table = mc13xxx_dt_ids, - }, - .probe = mc13xxx_probe, - .remove = __devexit_p(mc13xxx_remove), -}; - -static int __init mc13xxx_init(void) -{ - return spi_register_driver(&mc13xxx_driver); -} -subsys_initcall(mc13xxx_init); - -static void __exit mc13xxx_exit(void) -{ - spi_unregister_driver(&mc13xxx_driver); -} -module_exit(mc13xxx_exit); - -MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC"); -MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/mcp-core.c b/ANDROID_3.4.5/drivers/mfd/mcp-core.c deleted file mode 100644 index 62e5e361..00000000 --- a/ANDROID_3.4.5/drivers/mfd/mcp-core.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * linux/drivers/mfd/mcp-core.c - * - * Copyright (C) 2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * Generic MCP (Multimedia Communications Port) layer. All MCP locking - * is solely held within this file. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/smp.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/mfd/mcp.h> - - -#define to_mcp(d) container_of(d, struct mcp, attached_device) -#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) - -static int mcp_bus_match(struct device *dev, struct device_driver *drv) -{ - return 1; -} - -static int mcp_bus_probe(struct device *dev) -{ - struct mcp *mcp = to_mcp(dev); - struct mcp_driver *drv = to_mcp_driver(dev->driver); - - return drv->probe(mcp); -} - -static int mcp_bus_remove(struct device *dev) -{ - struct mcp *mcp = to_mcp(dev); - struct mcp_driver *drv = to_mcp_driver(dev->driver); - - drv->remove(mcp); - return 0; -} - -static struct bus_type mcp_bus_type = { - .name = "mcp", - .match = mcp_bus_match, - .probe = mcp_bus_probe, - .remove = mcp_bus_remove, -}; - -/** - * mcp_set_telecom_divisor - set the telecom divisor - * @mcp: MCP interface structure - * @div: SIB clock divisor - * - * Set the telecom divisor on the MCP interface. The resulting - * sample rate is SIBCLOCK/div. - */ -void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->set_telecom_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_set_telecom_divisor); - -/** - * mcp_set_audio_divisor - set the audio divisor - * @mcp: MCP interface structure - * @div: SIB clock divisor - * - * Set the audio divisor on the MCP interface. - */ -void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->set_audio_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_set_audio_divisor); - -/** - * mcp_reg_write - write a device register - * @mcp: MCP interface structure - * @reg: 4-bit register index - * @val: 16-bit data value - * - * Write a device register. The MCP interface must be enabled - * to prevent this function hanging. - */ -void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->reg_write(mcp, reg, val); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_reg_write); - -/** - * mcp_reg_read - read a device register - * @mcp: MCP interface structure - * @reg: 4-bit register index - * - * Read a device register and return its value. The MCP interface - * must be enabled to prevent this function hanging. - */ -unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg) -{ - unsigned long flags; - unsigned int val; - - spin_lock_irqsave(&mcp->lock, flags); - val = mcp->ops->reg_read(mcp, reg); - spin_unlock_irqrestore(&mcp->lock, flags); - - return val; -} -EXPORT_SYMBOL(mcp_reg_read); - -/** - * mcp_enable - enable the MCP interface - * @mcp: MCP interface to enable - * - * Enable the MCP interface. Each call to mcp_enable will need - * a corresponding call to mcp_disable to disable the interface. - */ -void mcp_enable(struct mcp *mcp) -{ - unsigned long flags; - spin_lock_irqsave(&mcp->lock, flags); - if (mcp->use_count++ == 0) - mcp->ops->enable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_enable); - -/** - * mcp_disable - disable the MCP interface - * @mcp: MCP interface to disable - * - * Disable the MCP interface. The MCP interface will only be - * disabled once the number of calls to mcp_enable matches the - * number of calls to mcp_disable. - */ -void mcp_disable(struct mcp *mcp) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - if (--mcp->use_count == 0) - mcp->ops->disable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_disable); - -static void mcp_release(struct device *dev) -{ - struct mcp *mcp = container_of(dev, struct mcp, attached_device); - - kfree(mcp); -} - -struct mcp *mcp_host_alloc(struct device *parent, size_t size) -{ - struct mcp *mcp; - - mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL); - if (mcp) { - spin_lock_init(&mcp->lock); - device_initialize(&mcp->attached_device); - mcp->attached_device.parent = parent; - mcp->attached_device.bus = &mcp_bus_type; - mcp->attached_device.dma_mask = parent->dma_mask; - mcp->attached_device.release = mcp_release; - } - return mcp; -} -EXPORT_SYMBOL(mcp_host_alloc); - -int mcp_host_add(struct mcp *mcp, void *pdata) -{ - mcp->attached_device.platform_data = pdata; - dev_set_name(&mcp->attached_device, "mcp0"); - return device_add(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_add); - -void mcp_host_del(struct mcp *mcp) -{ - device_del(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_del); - -void mcp_host_free(struct mcp *mcp) -{ - put_device(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_free); - -int mcp_driver_register(struct mcp_driver *mcpdrv) -{ - mcpdrv->drv.bus = &mcp_bus_type; - return driver_register(&mcpdrv->drv); -} -EXPORT_SYMBOL(mcp_driver_register); - -void mcp_driver_unregister(struct mcp_driver *mcpdrv) -{ - driver_unregister(&mcpdrv->drv); -} -EXPORT_SYMBOL(mcp_driver_unregister); - -static int __init mcp_init(void) -{ - return bus_register(&mcp_bus_type); -} - -static void __exit mcp_exit(void) -{ - bus_unregister(&mcp_bus_type); -} - -module_init(mcp_init); -module_exit(mcp_exit); - -MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); -MODULE_DESCRIPTION("Core multimedia communications port driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/mcp-sa11x0.c b/ANDROID_3.4.5/drivers/mfd/mcp-sa11x0.c deleted file mode 100644 index c54e244c..00000000 --- a/ANDROID_3.4.5/drivers/mfd/mcp-sa11x0.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * linux/drivers/mfd/mcp-sa11x0.c - * - * Copyright (C) 2001-2005 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * SA11x0 MCP (Multimedia Communications Port) driver. - * - * MCP read/write timeouts from Jordi Colomer, rehacked by rmk. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/mfd/mcp.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <mach/mcp.h> - -#define DRIVER_NAME "sa11x0-mcp" - -struct mcp_sa11x0 { - void __iomem *base0; - void __iomem *base1; - u32 mccr0; - u32 mccr1; -}; - -/* Register offsets */ -#define MCCR0(m) ((m)->base0 + 0x00) -#define MCDR0(m) ((m)->base0 + 0x08) -#define MCDR1(m) ((m)->base0 + 0x0c) -#define MCDR2(m) ((m)->base0 + 0x10) -#define MCSR(m) ((m)->base0 + 0x18) -#define MCCR1(m) ((m)->base1 + 0x00) - -#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) - -static void -mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) -{ - struct mcp_sa11x0 *m = priv(mcp); - - divisor /= 32; - - m->mccr0 &= ~0x00007f00; - m->mccr0 |= divisor << 8; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -static void -mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) -{ - struct mcp_sa11x0 *m = priv(mcp); - - divisor /= 32; - - m->mccr0 &= ~0x0000007f; - m->mccr0 |= divisor; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -/* - * Write data to the device. The bit should be set after 3 subframe - * times (each frame is 64 clocks). We wait a maximum of 6 subframes. - * We really should try doing something more productive while we - * wait. - */ -static void -mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) -{ - struct mcp_sa11x0 *m = priv(mcp); - int ret = -ETIME; - int i; - - writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m)); - - for (i = 0; i < 2; i++) { - udelay(mcp->rw_timeout); - if (readl_relaxed(MCSR(m)) & MCSR_CWC) { - ret = 0; - break; - } - } - - if (ret < 0) - printk(KERN_WARNING "mcp: write timed out\n"); -} - -/* - * Read data from the device. The bit should be set after 3 subframe - * times (each frame is 64 clocks). We wait a maximum of 6 subframes. - * We really should try doing something more productive while we - * wait. - */ -static unsigned int -mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) -{ - struct mcp_sa11x0 *m = priv(mcp); - int ret = -ETIME; - int i; - - writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m)); - - for (i = 0; i < 2; i++) { - udelay(mcp->rw_timeout); - if (readl_relaxed(MCSR(m)) & MCSR_CRC) { - ret = readl_relaxed(MCDR2(m)) & 0xffff; - break; - } - } - - if (ret < 0) - printk(KERN_WARNING "mcp: read timed out\n"); - - return ret; -} - -static void mcp_sa11x0_enable(struct mcp *mcp) -{ - struct mcp_sa11x0 *m = priv(mcp); - - writel(-1, MCSR(m)); - m->mccr0 |= MCCR0_MCE; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -static void mcp_sa11x0_disable(struct mcp *mcp) -{ - struct mcp_sa11x0 *m = priv(mcp); - - m->mccr0 &= ~MCCR0_MCE; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -/* - * Our methods. - */ -static struct mcp_ops mcp_sa11x0 = { - .set_telecom_divisor = mcp_sa11x0_set_telecom_divisor, - .set_audio_divisor = mcp_sa11x0_set_audio_divisor, - .reg_write = mcp_sa11x0_write, - .reg_read = mcp_sa11x0_read, - .enable = mcp_sa11x0_enable, - .disable = mcp_sa11x0_disable, -}; - -static int mcp_sa11x0_probe(struct platform_device *dev) -{ - struct mcp_plat_data *data = dev->dev.platform_data; - struct resource *mem0, *mem1; - struct mcp_sa11x0 *m; - struct mcp *mcp; - int ret; - - if (!data) - return -ENODEV; - - mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); - mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); - if (!mem0 || !mem1) - return -ENXIO; - - if (!request_mem_region(mem0->start, resource_size(mem0), - DRIVER_NAME)) { - ret = -EBUSY; - goto err_mem0; - } - - if (!request_mem_region(mem1->start, resource_size(mem1), - DRIVER_NAME)) { - ret = -EBUSY; - goto err_mem1; - } - - mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0)); - if (!mcp) { - ret = -ENOMEM; - goto err_alloc; - } - - mcp->owner = THIS_MODULE; - mcp->ops = &mcp_sa11x0; - mcp->sclk_rate = data->sclk_rate; - - m = priv(mcp); - m->mccr0 = data->mccr0 | 0x7f7f; - m->mccr1 = data->mccr1; - - m->base0 = ioremap(mem0->start, resource_size(mem0)); - m->base1 = ioremap(mem1->start, resource_size(mem1)); - if (!m->base0 || !m->base1) { - ret = -ENOMEM; - goto err_ioremap; - } - - platform_set_drvdata(dev, mcp); - - /* - * Initialise device. Note that we initially - * set the sampling rate to minimum. - */ - writel_relaxed(-1, MCSR(m)); - writel_relaxed(m->mccr1, MCCR1(m)); - writel_relaxed(m->mccr0, MCCR0(m)); - - /* - * Calculate the read/write timeout (us) from the bit clock - * rate. This is the period for 3 64-bit frames. Always - * round this time up. - */ - mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / - mcp->sclk_rate; - - ret = mcp_host_add(mcp, data->codec_pdata); - if (ret == 0) - return 0; - - platform_set_drvdata(dev, NULL); - - err_ioremap: - iounmap(m->base1); - iounmap(m->base0); - mcp_host_free(mcp); - err_alloc: - release_mem_region(mem1->start, resource_size(mem1)); - err_mem1: - release_mem_region(mem0->start, resource_size(mem0)); - err_mem0: - return ret; -} - -static int mcp_sa11x0_remove(struct platform_device *dev) -{ - struct mcp *mcp = platform_get_drvdata(dev); - struct mcp_sa11x0 *m = priv(mcp); - struct resource *mem0, *mem1; - - if (m->mccr0 & MCCR0_MCE) - dev_warn(&dev->dev, - "device left active (missing disable call?)\n"); - - mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); - mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); - - platform_set_drvdata(dev, NULL); - mcp_host_del(mcp); - iounmap(m->base1); - iounmap(m->base0); - mcp_host_free(mcp); - release_mem_region(mem1->start, resource_size(mem1)); - release_mem_region(mem0->start, resource_size(mem0)); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int mcp_sa11x0_suspend(struct device *dev) -{ - struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); - - if (m->mccr0 & MCCR0_MCE) - dev_warn(dev, "device left active (missing disable call?)\n"); - - writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m)); - - return 0; -} - -static int mcp_sa11x0_resume(struct device *dev) -{ - struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); - - writel_relaxed(m->mccr1, MCCR1(m)); - writel_relaxed(m->mccr0, MCCR0(m)); - - return 0; -} -#endif - -static const struct dev_pm_ops mcp_sa11x0_pm_ops = { -#ifdef CONFIG_PM_SLEEP - .suspend = mcp_sa11x0_suspend, - .freeze = mcp_sa11x0_suspend, - .poweroff = mcp_sa11x0_suspend, - .resume_noirq = mcp_sa11x0_resume, - .thaw_noirq = mcp_sa11x0_resume, - .restore_noirq = mcp_sa11x0_resume, -#endif -}; - -static struct platform_driver mcp_sa11x0_driver = { - .probe = mcp_sa11x0_probe, - .remove = mcp_sa11x0_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .pm = &mcp_sa11x0_pm_ops, - }, -}; - -/* - * This needs re-working - */ -module_platform_driver(mcp_sa11x0_driver); - -MODULE_ALIAS("platform:" DRIVER_NAME); -MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); -MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/menelaus.c b/ANDROID_3.4.5/drivers/mfd/menelaus.c deleted file mode 100644 index cb4910ac..00000000 --- a/ANDROID_3.4.5/drivers/mfd/menelaus.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* - * Copyright (C) 2004 Texas Instruments, Inc. - * - * Some parts based tps65010.c: - * Copyright (C) 2004 Texas Instruments and - * Copyright (C) 2004-2005 David Brownell - * - * Some parts based on tlv320aic24.c: - * Copyright (C) by Kai Svahn <kai.svahn@nokia.com> - * - * Changes for interrupt handling and clean-up by - * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com> - * Cleanup and generalized support for voltage setting by - * Juha Yrjola - * Added support for controlling VCORE and regulator sleep states, - * Amit Kucheria <amit.kucheria@nokia.com> - * Copyright (C) 2005, 2006 Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/sched.h> -#include <linux/mutex.h> -#include <linux/workqueue.h> -#include <linux/delay.h> -#include <linux/rtc.h> -#include <linux/bcd.h> -#include <linux/slab.h> - -#include <asm/mach/irq.h> - -#include <asm/gpio.h> -#include <plat/menelaus.h> - -#define DRIVER_NAME "menelaus" - -#define MENELAUS_I2C_ADDRESS 0x72 - -#define MENELAUS_REV 0x01 -#define MENELAUS_VCORE_CTRL1 0x02 -#define MENELAUS_VCORE_CTRL2 0x03 -#define MENELAUS_VCORE_CTRL3 0x04 -#define MENELAUS_VCORE_CTRL4 0x05 -#define MENELAUS_VCORE_CTRL5 0x06 -#define MENELAUS_DCDC_CTRL1 0x07 -#define MENELAUS_DCDC_CTRL2 0x08 -#define MENELAUS_DCDC_CTRL3 0x09 -#define MENELAUS_LDO_CTRL1 0x0A -#define MENELAUS_LDO_CTRL2 0x0B -#define MENELAUS_LDO_CTRL3 0x0C -#define MENELAUS_LDO_CTRL4 0x0D -#define MENELAUS_LDO_CTRL5 0x0E -#define MENELAUS_LDO_CTRL6 0x0F -#define MENELAUS_LDO_CTRL7 0x10 -#define MENELAUS_LDO_CTRL8 0x11 -#define MENELAUS_SLEEP_CTRL1 0x12 -#define MENELAUS_SLEEP_CTRL2 0x13 -#define MENELAUS_DEVICE_OFF 0x14 -#define MENELAUS_OSC_CTRL 0x15 -#define MENELAUS_DETECT_CTRL 0x16 -#define MENELAUS_INT_MASK1 0x17 -#define MENELAUS_INT_MASK2 0x18 -#define MENELAUS_INT_STATUS1 0x19 -#define MENELAUS_INT_STATUS2 0x1A -#define MENELAUS_INT_ACK1 0x1B -#define MENELAUS_INT_ACK2 0x1C -#define MENELAUS_GPIO_CTRL 0x1D -#define MENELAUS_GPIO_IN 0x1E -#define MENELAUS_GPIO_OUT 0x1F -#define MENELAUS_BBSMS 0x20 -#define MENELAUS_RTC_CTRL 0x21 -#define MENELAUS_RTC_UPDATE 0x22 -#define MENELAUS_RTC_SEC 0x23 -#define MENELAUS_RTC_MIN 0x24 -#define MENELAUS_RTC_HR 0x25 -#define MENELAUS_RTC_DAY 0x26 -#define MENELAUS_RTC_MON 0x27 -#define MENELAUS_RTC_YR 0x28 -#define MENELAUS_RTC_WKDAY 0x29 -#define MENELAUS_RTC_AL_SEC 0x2A -#define MENELAUS_RTC_AL_MIN 0x2B -#define MENELAUS_RTC_AL_HR 0x2C -#define MENELAUS_RTC_AL_DAY 0x2D -#define MENELAUS_RTC_AL_MON 0x2E -#define MENELAUS_RTC_AL_YR 0x2F -#define MENELAUS_RTC_COMP_MSB 0x30 -#define MENELAUS_RTC_COMP_LSB 0x31 -#define MENELAUS_S1_PULL_EN 0x32 -#define MENELAUS_S1_PULL_DIR 0x33 -#define MENELAUS_S2_PULL_EN 0x34 -#define MENELAUS_S2_PULL_DIR 0x35 -#define MENELAUS_MCT_CTRL1 0x36 -#define MENELAUS_MCT_CTRL2 0x37 -#define MENELAUS_MCT_CTRL3 0x38 -#define MENELAUS_MCT_PIN_ST 0x39 -#define MENELAUS_DEBOUNCE1 0x3A - -#define IH_MENELAUS_IRQS 12 -#define MENELAUS_MMC_S1CD_IRQ 0 /* MMC slot 1 card change */ -#define MENELAUS_MMC_S2CD_IRQ 1 /* MMC slot 2 card change */ -#define MENELAUS_MMC_S1D1_IRQ 2 /* MMC DAT1 low in slot 1 */ -#define MENELAUS_MMC_S2D1_IRQ 3 /* MMC DAT1 low in slot 2 */ -#define MENELAUS_LOWBAT_IRQ 4 /* Low battery */ -#define MENELAUS_HOTDIE_IRQ 5 /* Hot die detect */ -#define MENELAUS_UVLO_IRQ 6 /* UVLO detect */ -#define MENELAUS_TSHUT_IRQ 7 /* Thermal shutdown */ -#define MENELAUS_RTCTMR_IRQ 8 /* RTC timer */ -#define MENELAUS_RTCALM_IRQ 9 /* RTC alarm */ -#define MENELAUS_RTCERR_IRQ 10 /* RTC error */ -#define MENELAUS_PSHBTN_IRQ 11 /* Push button */ -#define MENELAUS_RESERVED12_IRQ 12 /* Reserved */ -#define MENELAUS_RESERVED13_IRQ 13 /* Reserved */ -#define MENELAUS_RESERVED14_IRQ 14 /* Reserved */ -#define MENELAUS_RESERVED15_IRQ 15 /* Reserved */ - -/* VCORE_CTRL1 register */ -#define VCORE_CTRL1_BYP_COMP (1 << 5) -#define VCORE_CTRL1_HW_NSW (1 << 7) - -/* GPIO_CTRL register */ -#define GPIO_CTRL_SLOTSELEN (1 << 5) -#define GPIO_CTRL_SLPCTLEN (1 << 6) -#define GPIO1_DIR_INPUT (1 << 0) -#define GPIO2_DIR_INPUT (1 << 1) -#define GPIO3_DIR_INPUT (1 << 2) - -/* MCT_CTRL1 register */ -#define MCT_CTRL1_S1_CMD_OD (1 << 2) -#define MCT_CTRL1_S2_CMD_OD (1 << 3) - -/* MCT_CTRL2 register */ -#define MCT_CTRL2_VS2_SEL_D0 (1 << 0) -#define MCT_CTRL2_VS2_SEL_D1 (1 << 1) -#define MCT_CTRL2_S1CD_BUFEN (1 << 4) -#define MCT_CTRL2_S2CD_BUFEN (1 << 5) -#define MCT_CTRL2_S1CD_DBEN (1 << 6) -#define MCT_CTRL2_S2CD_BEN (1 << 7) - -/* MCT_CTRL3 register */ -#define MCT_CTRL3_SLOT1_EN (1 << 0) -#define MCT_CTRL3_SLOT2_EN (1 << 1) -#define MCT_CTRL3_S1_AUTO_EN (1 << 2) -#define MCT_CTRL3_S2_AUTO_EN (1 << 3) - -/* MCT_PIN_ST register */ -#define MCT_PIN_ST_S1_CD_ST (1 << 0) -#define MCT_PIN_ST_S2_CD_ST (1 << 1) - -static void menelaus_work(struct work_struct *_menelaus); - -struct menelaus_chip { - struct mutex lock; - struct i2c_client *client; - struct work_struct work; -#ifdef CONFIG_RTC_DRV_TWL92330 - struct rtc_device *rtc; - u8 rtc_control; - unsigned uie:1; -#endif - unsigned vcore_hw_mode:1; - u8 mask1, mask2; - void (*handlers[16])(struct menelaus_chip *); - void (*mmc_callback)(void *data, u8 mask); - void *mmc_callback_data; -}; - -static struct menelaus_chip *the_menelaus; - -static int menelaus_write_reg(int reg, u8 value) -{ - int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value); - - if (val < 0) { - pr_err(DRIVER_NAME ": write error"); - return val; - } - - return 0; -} - -static int menelaus_read_reg(int reg) -{ - int val = i2c_smbus_read_byte_data(the_menelaus->client, reg); - - if (val < 0) - pr_err(DRIVER_NAME ": read error"); - - return val; -} - -static int menelaus_enable_irq(int irq) -{ - if (irq > 7) { - irq -= 8; - the_menelaus->mask2 &= ~(1 << irq); - return menelaus_write_reg(MENELAUS_INT_MASK2, - the_menelaus->mask2); - } else { - the_menelaus->mask1 &= ~(1 << irq); - return menelaus_write_reg(MENELAUS_INT_MASK1, - the_menelaus->mask1); - } -} - -static int menelaus_disable_irq(int irq) -{ - if (irq > 7) { - irq -= 8; - the_menelaus->mask2 |= (1 << irq); - return menelaus_write_reg(MENELAUS_INT_MASK2, - the_menelaus->mask2); - } else { - the_menelaus->mask1 |= (1 << irq); - return menelaus_write_reg(MENELAUS_INT_MASK1, - the_menelaus->mask1); - } -} - -static int menelaus_ack_irq(int irq) -{ - if (irq > 7) - return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8)); - else - return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq); -} - -/* Adds a handler for an interrupt. Does not run in interrupt context */ -static int menelaus_add_irq_work(int irq, - void (*handler)(struct menelaus_chip *)) -{ - int ret = 0; - - mutex_lock(&the_menelaus->lock); - the_menelaus->handlers[irq] = handler; - ret = menelaus_enable_irq(irq); - mutex_unlock(&the_menelaus->lock); - - return ret; -} - -/* Removes handler for an interrupt */ -static int menelaus_remove_irq_work(int irq) -{ - int ret = 0; - - mutex_lock(&the_menelaus->lock); - ret = menelaus_disable_irq(irq); - the_menelaus->handlers[irq] = NULL; - mutex_unlock(&the_menelaus->lock); - - return ret; -} - -/* - * Gets scheduled when a card detect interrupt happens. Note that in some cases - * this line is wired to card cover switch rather than the card detect switch - * in each slot. In this case the cards are not seen by menelaus. - * FIXME: Add handling for D1 too - */ -static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw) -{ - int reg; - unsigned char card_mask = 0; - - reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST); - if (reg < 0) - return; - - if (!(reg & 0x1)) - card_mask |= MCT_PIN_ST_S1_CD_ST; - - if (!(reg & 0x2)) - card_mask |= MCT_PIN_ST_S2_CD_ST; - - if (menelaus_hw->mmc_callback) - menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data, - card_mask); -} - -/* - * Toggles the MMC slots between open-drain and push-pull mode. - */ -int menelaus_set_mmc_opendrain(int slot, int enable) -{ - int ret, val; - - if (slot != 1 && slot != 2) - return -EINVAL; - mutex_lock(&the_menelaus->lock); - ret = menelaus_read_reg(MENELAUS_MCT_CTRL1); - if (ret < 0) { - mutex_unlock(&the_menelaus->lock); - return ret; - } - val = ret; - if (slot == 1) { - if (enable) - val |= MCT_CTRL1_S1_CMD_OD; - else - val &= ~MCT_CTRL1_S1_CMD_OD; - } else { - if (enable) - val |= MCT_CTRL1_S2_CMD_OD; - else - val &= ~MCT_CTRL1_S2_CMD_OD; - } - ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val); - mutex_unlock(&the_menelaus->lock); - - return ret; -} -EXPORT_SYMBOL(menelaus_set_mmc_opendrain); - -int menelaus_set_slot_sel(int enable) -{ - int ret; - - mutex_lock(&the_menelaus->lock); - ret = menelaus_read_reg(MENELAUS_GPIO_CTRL); - if (ret < 0) - goto out; - ret |= GPIO2_DIR_INPUT; - if (enable) - ret |= GPIO_CTRL_SLOTSELEN; - else - ret &= ~GPIO_CTRL_SLOTSELEN; - ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret); -out: - mutex_unlock(&the_menelaus->lock); - return ret; -} -EXPORT_SYMBOL(menelaus_set_slot_sel); - -int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en) -{ - int ret, val; - - if (slot != 1 && slot != 2) - return -EINVAL; - if (power >= 3) - return -EINVAL; - - mutex_lock(&the_menelaus->lock); - - ret = menelaus_read_reg(MENELAUS_MCT_CTRL2); - if (ret < 0) - goto out; - val = ret; - if (slot == 1) { - if (cd_en) - val |= MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN; - else - val &= ~(MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN); - } else { - if (cd_en) - val |= MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN; - else - val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN); - } - ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val); - if (ret < 0) - goto out; - - ret = menelaus_read_reg(MENELAUS_MCT_CTRL3); - if (ret < 0) - goto out; - val = ret; - if (slot == 1) { - if (enable) - val |= MCT_CTRL3_SLOT1_EN; - else - val &= ~MCT_CTRL3_SLOT1_EN; - } else { - int b; - - if (enable) - val |= MCT_CTRL3_SLOT2_EN; - else - val &= ~MCT_CTRL3_SLOT2_EN; - b = menelaus_read_reg(MENELAUS_MCT_CTRL2); - b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1); - b |= power; - ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b); - if (ret < 0) - goto out; - } - /* Disable autonomous shutdown */ - val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN); - ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val); -out: - mutex_unlock(&the_menelaus->lock); - return ret; -} -EXPORT_SYMBOL(menelaus_set_mmc_slot); - -int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask), - void *data) -{ - int ret = 0; - - the_menelaus->mmc_callback_data = data; - the_menelaus->mmc_callback = callback; - ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ, - menelaus_mmc_cd_work); - if (ret < 0) - return ret; - ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ, - menelaus_mmc_cd_work); - if (ret < 0) - return ret; - ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ, - menelaus_mmc_cd_work); - if (ret < 0) - return ret; - ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ, - menelaus_mmc_cd_work); - - return ret; -} -EXPORT_SYMBOL(menelaus_register_mmc_callback); - -void menelaus_unregister_mmc_callback(void) -{ - menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ); - menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ); - menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ); - menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ); - - the_menelaus->mmc_callback = NULL; - the_menelaus->mmc_callback_data = 0; -} -EXPORT_SYMBOL(menelaus_unregister_mmc_callback); - -struct menelaus_vtg { - const char *name; - u8 vtg_reg; - u8 vtg_shift; - u8 vtg_bits; - u8 mode_reg; -}; - -struct menelaus_vtg_value { - u16 vtg; - u16 val; -}; - -static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV, - int vtg_val, int mode) -{ - int val, ret; - struct i2c_client *c = the_menelaus->client; - - mutex_lock(&the_menelaus->lock); - if (vtg == 0) - goto set_voltage; - - ret = menelaus_read_reg(vtg->vtg_reg); - if (ret < 0) - goto out; - val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift); - val |= vtg_val << vtg->vtg_shift; - - dev_dbg(&c->dev, "Setting voltage '%s'" - "to %d mV (reg 0x%02x, val 0x%02x)\n", - vtg->name, mV, vtg->vtg_reg, val); - - ret = menelaus_write_reg(vtg->vtg_reg, val); - if (ret < 0) - goto out; -set_voltage: - ret = menelaus_write_reg(vtg->mode_reg, mode); -out: - mutex_unlock(&the_menelaus->lock); - if (ret == 0) { - /* Wait for voltage to stabilize */ - msleep(1); - } - return ret; -} - -static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl, - int n) -{ - int i; - - for (i = 0; i < n; i++, tbl++) - if (tbl->vtg == vtg) - return tbl->val; - return -EINVAL; -} - -/* - * Vcore can be programmed in two ways: - * SW-controlled: Required voltage is programmed into VCORE_CTRL1 - * HW-controlled: Required range (roof-floor) is programmed into VCORE_CTRL3 - * and VCORE_CTRL4 - * - * Call correct 'set' function accordingly - */ - -static const struct menelaus_vtg_value vcore_values[] = { - { 1000, 0 }, - { 1025, 1 }, - { 1050, 2 }, - { 1075, 3 }, - { 1100, 4 }, - { 1125, 5 }, - { 1150, 6 }, - { 1175, 7 }, - { 1200, 8 }, - { 1225, 9 }, - { 1250, 10 }, - { 1275, 11 }, - { 1300, 12 }, - { 1325, 13 }, - { 1350, 14 }, - { 1375, 15 }, - { 1400, 16 }, - { 1425, 17 }, - { 1450, 18 }, -}; - -int menelaus_set_vcore_sw(unsigned int mV) -{ - int val, ret; - struct i2c_client *c = the_menelaus->client; - - val = menelaus_get_vtg_value(mV, vcore_values, - ARRAY_SIZE(vcore_values)); - if (val < 0) - return -EINVAL; - - dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val); - - /* Set SW mode and the voltage in one go. */ - mutex_lock(&the_menelaus->lock); - ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val); - if (ret == 0) - the_menelaus->vcore_hw_mode = 0; - mutex_unlock(&the_menelaus->lock); - msleep(1); - - return ret; -} - -int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV) -{ - int fval, rval, val, ret; - struct i2c_client *c = the_menelaus->client; - - rval = menelaus_get_vtg_value(roof_mV, vcore_values, - ARRAY_SIZE(vcore_values)); - if (rval < 0) - return -EINVAL; - fval = menelaus_get_vtg_value(floor_mV, vcore_values, - ARRAY_SIZE(vcore_values)); - if (fval < 0) - return -EINVAL; - - dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n", - floor_mV, roof_mV); - - mutex_lock(&the_menelaus->lock); - ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval); - if (ret < 0) - goto out; - ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval); - if (ret < 0) - goto out; - if (!the_menelaus->vcore_hw_mode) { - val = menelaus_read_reg(MENELAUS_VCORE_CTRL1); - /* HW mode, turn OFF byte comparator */ - val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP); - ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val); - the_menelaus->vcore_hw_mode = 1; - } - msleep(1); -out: - mutex_unlock(&the_menelaus->lock); - return ret; -} - -static const struct menelaus_vtg vmem_vtg = { - .name = "VMEM", - .vtg_reg = MENELAUS_LDO_CTRL1, - .vtg_shift = 0, - .vtg_bits = 2, - .mode_reg = MENELAUS_LDO_CTRL3, -}; - -static const struct menelaus_vtg_value vmem_values[] = { - { 1500, 0 }, - { 1800, 1 }, - { 1900, 2 }, - { 2500, 3 }, -}; - -int menelaus_set_vmem(unsigned int mV) -{ - int val; - - if (mV == 0) - return menelaus_set_voltage(&vmem_vtg, 0, 0, 0); - - val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values)); - if (val < 0) - return -EINVAL; - return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02); -} -EXPORT_SYMBOL(menelaus_set_vmem); - -static const struct menelaus_vtg vio_vtg = { - .name = "VIO", - .vtg_reg = MENELAUS_LDO_CTRL1, - .vtg_shift = 2, - .vtg_bits = 2, - .mode_reg = MENELAUS_LDO_CTRL4, -}; - -static const struct menelaus_vtg_value vio_values[] = { - { 1500, 0 }, - { 1800, 1 }, - { 2500, 2 }, - { 2800, 3 }, -}; - -int menelaus_set_vio(unsigned int mV) -{ - int val; - - if (mV == 0) - return menelaus_set_voltage(&vio_vtg, 0, 0, 0); - - val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values)); - if (val < 0) - return -EINVAL; - return menelaus_set_voltage(&vio_vtg, mV, val, 0x02); -} -EXPORT_SYMBOL(menelaus_set_vio); - -static const struct menelaus_vtg_value vdcdc_values[] = { - { 1500, 0 }, - { 1800, 1 }, - { 2000, 2 }, - { 2200, 3 }, - { 2400, 4 }, - { 2800, 5 }, - { 3000, 6 }, - { 3300, 7 }, -}; - -static const struct menelaus_vtg vdcdc2_vtg = { - .name = "VDCDC2", - .vtg_reg = MENELAUS_DCDC_CTRL1, - .vtg_shift = 0, - .vtg_bits = 3, - .mode_reg = MENELAUS_DCDC_CTRL2, -}; - -static const struct menelaus_vtg vdcdc3_vtg = { - .name = "VDCDC3", - .vtg_reg = MENELAUS_DCDC_CTRL1, - .vtg_shift = 3, - .vtg_bits = 3, - .mode_reg = MENELAUS_DCDC_CTRL3, -}; - -int menelaus_set_vdcdc(int dcdc, unsigned int mV) -{ - const struct menelaus_vtg *vtg; - int val; - - if (dcdc != 2 && dcdc != 3) - return -EINVAL; - if (dcdc == 2) - vtg = &vdcdc2_vtg; - else - vtg = &vdcdc3_vtg; - - if (mV == 0) - return menelaus_set_voltage(vtg, 0, 0, 0); - - val = menelaus_get_vtg_value(mV, vdcdc_values, - ARRAY_SIZE(vdcdc_values)); - if (val < 0) - return -EINVAL; - return menelaus_set_voltage(vtg, mV, val, 0x03); -} - -static const struct menelaus_vtg_value vmmc_values[] = { - { 1850, 0 }, - { 2800, 1 }, - { 3000, 2 }, - { 3100, 3 }, -}; - -static const struct menelaus_vtg vmmc_vtg = { - .name = "VMMC", - .vtg_reg = MENELAUS_LDO_CTRL1, - .vtg_shift = 6, - .vtg_bits = 2, - .mode_reg = MENELAUS_LDO_CTRL7, -}; - -int menelaus_set_vmmc(unsigned int mV) -{ - int val; - - if (mV == 0) - return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0); - - val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values)); - if (val < 0) - return -EINVAL; - return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02); -} -EXPORT_SYMBOL(menelaus_set_vmmc); - - -static const struct menelaus_vtg_value vaux_values[] = { - { 1500, 0 }, - { 1800, 1 }, - { 2500, 2 }, - { 2800, 3 }, -}; - -static const struct menelaus_vtg vaux_vtg = { - .name = "VAUX", - .vtg_reg = MENELAUS_LDO_CTRL1, - .vtg_shift = 4, - .vtg_bits = 2, - .mode_reg = MENELAUS_LDO_CTRL6, -}; - -int menelaus_set_vaux(unsigned int mV) -{ - int val; - - if (mV == 0) - return menelaus_set_voltage(&vaux_vtg, 0, 0, 0); - - val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values)); - if (val < 0) - return -EINVAL; - return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02); -} -EXPORT_SYMBOL(menelaus_set_vaux); - -int menelaus_get_slot_pin_states(void) -{ - return menelaus_read_reg(MENELAUS_MCT_PIN_ST); -} -EXPORT_SYMBOL(menelaus_get_slot_pin_states); - -int menelaus_set_regulator_sleep(int enable, u32 val) -{ - int t, ret; - struct i2c_client *c = the_menelaus->client; - - mutex_lock(&the_menelaus->lock); - ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val); - if (ret < 0) - goto out; - - dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val); - - ret = menelaus_read_reg(MENELAUS_GPIO_CTRL); - if (ret < 0) - goto out; - t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT); - if (enable) - ret |= t; - else - ret &= ~t; - ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret); -out: - mutex_unlock(&the_menelaus->lock); - return ret; -} - -/*-----------------------------------------------------------------------*/ - -/* Handles Menelaus interrupts. Does not run in interrupt context */ -static void menelaus_work(struct work_struct *_menelaus) -{ - struct menelaus_chip *menelaus = - container_of(_menelaus, struct menelaus_chip, work); - void (*handler)(struct menelaus_chip *menelaus); - - while (1) { - unsigned isr; - - isr = (menelaus_read_reg(MENELAUS_INT_STATUS2) - & ~menelaus->mask2) << 8; - isr |= menelaus_read_reg(MENELAUS_INT_STATUS1) - & ~menelaus->mask1; - if (!isr) - break; - - while (isr) { - int irq = fls(isr) - 1; - isr &= ~(1 << irq); - - mutex_lock(&menelaus->lock); - menelaus_disable_irq(irq); - menelaus_ack_irq(irq); - handler = menelaus->handlers[irq]; - if (handler) - handler(menelaus); - menelaus_enable_irq(irq); - mutex_unlock(&menelaus->lock); - } - } - enable_irq(menelaus->client->irq); -} - -/* - * We cannot use I2C in interrupt context, so we just schedule work. - */ -static irqreturn_t menelaus_irq(int irq, void *_menelaus) -{ - struct menelaus_chip *menelaus = _menelaus; - - disable_irq_nosync(irq); - (void)schedule_work(&menelaus->work); - - return IRQ_HANDLED; -} - -/*-----------------------------------------------------------------------*/ - -/* - * The RTC needs to be set once, then it runs on backup battery power. - * It supports alarms, including system wake alarms (from some modes); - * and 1/second IRQs if requested. - */ -#ifdef CONFIG_RTC_DRV_TWL92330 - -#define RTC_CTRL_RTC_EN (1 << 0) -#define RTC_CTRL_AL_EN (1 << 1) -#define RTC_CTRL_MODE12 (1 << 2) -#define RTC_CTRL_EVERY_MASK (3 << 3) -#define RTC_CTRL_EVERY_SEC (0 << 3) -#define RTC_CTRL_EVERY_MIN (1 << 3) -#define RTC_CTRL_EVERY_HR (2 << 3) -#define RTC_CTRL_EVERY_DAY (3 << 3) - -#define RTC_UPDATE_EVERY 0x08 - -#define RTC_HR_PM (1 << 7) - -static void menelaus_to_time(char *regs, struct rtc_time *t) -{ - t->tm_sec = bcd2bin(regs[0]); - t->tm_min = bcd2bin(regs[1]); - if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { - t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1; - if (regs[2] & RTC_HR_PM) - t->tm_hour += 12; - } else - t->tm_hour = bcd2bin(regs[2] & 0x3f); - t->tm_mday = bcd2bin(regs[3]); - t->tm_mon = bcd2bin(regs[4]) - 1; - t->tm_year = bcd2bin(regs[5]) + 100; -} - -static int time_to_menelaus(struct rtc_time *t, int regnum) -{ - int hour, status; - - status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec)); - if (status < 0) - goto fail; - - status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min)); - if (status < 0) - goto fail; - - if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { - hour = t->tm_hour + 1; - if (hour > 12) - hour = RTC_HR_PM | bin2bcd(hour - 12); - else - hour = bin2bcd(hour); - } else - hour = bin2bcd(t->tm_hour); - status = menelaus_write_reg(regnum++, hour); - if (status < 0) - goto fail; - - status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday)); - if (status < 0) - goto fail; - - status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1)); - if (status < 0) - goto fail; - - status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100)); - if (status < 0) - goto fail; - - return 0; -fail: - dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n", - --regnum, status); - return status; -} - -static int menelaus_read_time(struct device *dev, struct rtc_time *t) -{ - struct i2c_msg msg[2]; - char regs[7]; - int status; - - /* block read date and time registers */ - regs[0] = MENELAUS_RTC_SEC; - - msg[0].addr = MENELAUS_I2C_ADDRESS; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = regs; - - msg[1].addr = MENELAUS_I2C_ADDRESS; - msg[1].flags = I2C_M_RD; - msg[1].len = sizeof(regs); - msg[1].buf = regs; - - status = i2c_transfer(the_menelaus->client->adapter, msg, 2); - if (status != 2) { - dev_err(dev, "%s error %d\n", "read", status); - return -EIO; - } - - menelaus_to_time(regs, t); - t->tm_wday = bcd2bin(regs[6]); - - return 0; -} - -static int menelaus_set_time(struct device *dev, struct rtc_time *t) -{ - int status; - - /* write date and time registers */ - status = time_to_menelaus(t, MENELAUS_RTC_SEC); - if (status < 0) - return status; - status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday)); - if (status < 0) { - dev_err(&the_menelaus->client->dev, "rtc write reg %02x " - "err %d\n", MENELAUS_RTC_WKDAY, status); - return status; - } - - /* now commit the write */ - status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY); - if (status < 0) - dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n", - status); - - return 0; -} - -static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w) -{ - struct i2c_msg msg[2]; - char regs[6]; - int status; - - /* block read alarm registers */ - regs[0] = MENELAUS_RTC_AL_SEC; - - msg[0].addr = MENELAUS_I2C_ADDRESS; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = regs; - - msg[1].addr = MENELAUS_I2C_ADDRESS; - msg[1].flags = I2C_M_RD; - msg[1].len = sizeof(regs); - msg[1].buf = regs; - - status = i2c_transfer(the_menelaus->client->adapter, msg, 2); - if (status != 2) { - dev_err(dev, "%s error %d\n", "alarm read", status); - return -EIO; - } - - menelaus_to_time(regs, &w->time); - - w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN); - - /* NOTE we *could* check if actually pending... */ - w->pending = 0; - - return 0; -} - -static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w) -{ - int status; - - if (the_menelaus->client->irq <= 0 && w->enabled) - return -ENODEV; - - /* clear previous alarm enable */ - if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) { - the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN; - status = menelaus_write_reg(MENELAUS_RTC_CTRL, - the_menelaus->rtc_control); - if (status < 0) - return status; - } - - /* write alarm registers */ - status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC); - if (status < 0) - return status; - - /* enable alarm if requested */ - if (w->enabled) { - the_menelaus->rtc_control |= RTC_CTRL_AL_EN; - status = menelaus_write_reg(MENELAUS_RTC_CTRL, - the_menelaus->rtc_control); - } - - return status; -} - -#ifdef CONFIG_RTC_INTF_DEV - -static void menelaus_rtc_update_work(struct menelaus_chip *m) -{ - /* report 1/sec update */ - local_irq_disable(); - rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF); - local_irq_enable(); -} - -static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg) -{ - int status; - - if (the_menelaus->client->irq <= 0) - return -ENOIOCTLCMD; - - switch (cmd) { - /* alarm IRQ */ - case RTC_AIE_ON: - if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) - return 0; - the_menelaus->rtc_control |= RTC_CTRL_AL_EN; - break; - case RTC_AIE_OFF: - if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN)) - return 0; - the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN; - break; - /* 1/second "update" IRQ */ - case RTC_UIE_ON: - if (the_menelaus->uie) - return 0; - status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ); - status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ, - menelaus_rtc_update_work); - if (status == 0) - the_menelaus->uie = 1; - return status; - case RTC_UIE_OFF: - if (!the_menelaus->uie) - return 0; - status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ); - if (status == 0) - the_menelaus->uie = 0; - return status; - default: - return -ENOIOCTLCMD; - } - return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control); -} - -#else -#define menelaus_ioctl NULL -#endif - -/* REVISIT no compensation register support ... */ - -static const struct rtc_class_ops menelaus_rtc_ops = { - .ioctl = menelaus_ioctl, - .read_time = menelaus_read_time, - .set_time = menelaus_set_time, - .read_alarm = menelaus_read_alarm, - .set_alarm = menelaus_set_alarm, -}; - -static void menelaus_rtc_alarm_work(struct menelaus_chip *m) -{ - /* report alarm */ - local_irq_disable(); - rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF); - local_irq_enable(); - - /* then disable it; alarms are oneshot */ - the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN; - menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control); -} - -static inline void menelaus_rtc_init(struct menelaus_chip *m) -{ - int alarm = (m->client->irq > 0); - - /* assume 32KDETEN pin is pulled high */ - if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) { - dev_dbg(&m->client->dev, "no 32k oscillator\n"); - return; - } - - /* support RTC alarm; it can issue wakeups */ - if (alarm) { - if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ, - menelaus_rtc_alarm_work) < 0) { - dev_err(&m->client->dev, "can't handle RTC alarm\n"); - return; - } - device_init_wakeup(&m->client->dev, 1); - } - - /* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */ - m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL); - if (!(m->rtc_control & RTC_CTRL_RTC_EN) - || (m->rtc_control & RTC_CTRL_AL_EN) - || (m->rtc_control & RTC_CTRL_EVERY_MASK)) { - if (!(m->rtc_control & RTC_CTRL_RTC_EN)) { - dev_warn(&m->client->dev, "rtc clock needs setting\n"); - m->rtc_control |= RTC_CTRL_RTC_EN; - } - m->rtc_control &= ~RTC_CTRL_EVERY_MASK; - m->rtc_control &= ~RTC_CTRL_AL_EN; - menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control); - } - - m->rtc = rtc_device_register(DRIVER_NAME, - &m->client->dev, - &menelaus_rtc_ops, THIS_MODULE); - if (IS_ERR(m->rtc)) { - if (alarm) { - menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ); - device_init_wakeup(&m->client->dev, 0); - } - dev_err(&m->client->dev, "can't register RTC: %d\n", - (int) PTR_ERR(m->rtc)); - the_menelaus->rtc = NULL; - } -} - -#else - -static inline void menelaus_rtc_init(struct menelaus_chip *m) -{ - /* nothing */ -} - -#endif - -/*-----------------------------------------------------------------------*/ - -static struct i2c_driver menelaus_i2c_driver; - -static int menelaus_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct menelaus_chip *menelaus; - int rev = 0, val; - int err = 0; - struct menelaus_platform_data *menelaus_pdata = - client->dev.platform_data; - - if (the_menelaus) { - dev_dbg(&client->dev, "only one %s for now\n", - DRIVER_NAME); - return -ENODEV; - } - - menelaus = kzalloc(sizeof *menelaus, GFP_KERNEL); - if (!menelaus) - return -ENOMEM; - - i2c_set_clientdata(client, menelaus); - - the_menelaus = menelaus; - menelaus->client = client; - - /* If a true probe check the device */ - rev = menelaus_read_reg(MENELAUS_REV); - if (rev < 0) { - pr_err(DRIVER_NAME ": device not found"); - err = -ENODEV; - goto fail1; - } - - /* Ack and disable all Menelaus interrupts */ - menelaus_write_reg(MENELAUS_INT_ACK1, 0xff); - menelaus_write_reg(MENELAUS_INT_ACK2, 0xff); - menelaus_write_reg(MENELAUS_INT_MASK1, 0xff); - menelaus_write_reg(MENELAUS_INT_MASK2, 0xff); - menelaus->mask1 = 0xff; - menelaus->mask2 = 0xff; - - /* Set output buffer strengths */ - menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73); - - if (client->irq > 0) { - err = request_irq(client->irq, menelaus_irq, 0, - DRIVER_NAME, menelaus); - if (err) { - dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", - client->irq, err); - goto fail1; - } - } - - mutex_init(&menelaus->lock); - INIT_WORK(&menelaus->work, menelaus_work); - - pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f); - - val = menelaus_read_reg(MENELAUS_VCORE_CTRL1); - if (val < 0) - goto fail2; - if (val & (1 << 7)) - menelaus->vcore_hw_mode = 1; - else - menelaus->vcore_hw_mode = 0; - - if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) { - err = menelaus_pdata->late_init(&client->dev); - if (err < 0) - goto fail2; - } - - menelaus_rtc_init(menelaus); - - return 0; -fail2: - free_irq(client->irq, menelaus); - flush_work_sync(&menelaus->work); -fail1: - kfree(menelaus); - return err; -} - -static int __exit menelaus_remove(struct i2c_client *client) -{ - struct menelaus_chip *menelaus = i2c_get_clientdata(client); - - free_irq(client->irq, menelaus); - flush_work_sync(&menelaus->work); - kfree(menelaus); - the_menelaus = NULL; - return 0; -} - -static const struct i2c_device_id menelaus_id[] = { - { "menelaus", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, menelaus_id); - -static struct i2c_driver menelaus_i2c_driver = { - .driver = { - .name = DRIVER_NAME, - }, - .probe = menelaus_probe, - .remove = __exit_p(menelaus_remove), - .id_table = menelaus_id, -}; - -static int __init menelaus_init(void) -{ - int res; - - res = i2c_add_driver(&menelaus_i2c_driver); - if (res < 0) { - pr_err(DRIVER_NAME ": driver registration failed\n"); - return res; - } - - return 0; -} - -static void __exit menelaus_exit(void) -{ - i2c_del_driver(&menelaus_i2c_driver); - - /* FIXME: Shutdown menelaus parts that can be shut down */ -} - -MODULE_AUTHOR("Texas Instruments, Inc. (and others)"); -MODULE_DESCRIPTION("I2C interface for Menelaus."); -MODULE_LICENSE("GPL"); - -module_init(menelaus_init); -module_exit(menelaus_exit); diff --git a/ANDROID_3.4.5/drivers/mfd/mfd-core.c b/ANDROID_3.4.5/drivers/mfd/mfd-core.c deleted file mode 100644 index ffc3d486..00000000 --- a/ANDROID_3.4.5/drivers/mfd/mfd-core.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * drivers/mfd/mfd-core.c - * - * core MFD support - * Copyright (c) 2006 Ian Molton - * Copyright (c) 2007,2008 Dmitry Baryshkov - * - * 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/kernel.h> -#include <linux/platform_device.h> -#include <linux/acpi.h> -#include <linux/mfd/core.h> -#include <linux/pm_runtime.h> -#include <linux/slab.h> -#include <linux/module.h> - -int mfd_cell_enable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - int err = 0; - - /* only call enable hook if the cell wasn't previously enabled */ - if (atomic_inc_return(cell->usage_count) == 1) - err = cell->enable(pdev); - - /* if the enable hook failed, decrement counter to allow retries */ - if (err) - atomic_dec(cell->usage_count); - - return err; -} -EXPORT_SYMBOL(mfd_cell_enable); - -int mfd_cell_disable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - int err = 0; - - /* only disable if no other clients are using it */ - if (atomic_dec_return(cell->usage_count) == 0) - err = cell->disable(pdev); - - /* if the disable hook failed, increment to allow retries */ - if (err) - atomic_inc(cell->usage_count); - - /* sanity check; did someone call disable too many times? */ - WARN_ON(atomic_read(cell->usage_count) < 0); - - return err; -} -EXPORT_SYMBOL(mfd_cell_disable); - -static int mfd_platform_add_cell(struct platform_device *pdev, - const struct mfd_cell *cell) -{ - if (!cell) - return 0; - - pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL); - if (!pdev->mfd_cell) - return -ENOMEM; - - return 0; -} - -static int mfd_add_device(struct device *parent, int id, - const struct mfd_cell *cell, - struct resource *mem_base, - int irq_base) -{ - struct resource *res; - struct platform_device *pdev; - int ret = -ENOMEM; - int r; - - pdev = platform_device_alloc(cell->name, id + cell->id); - if (!pdev) - goto fail_alloc; - - res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL); - if (!res) - goto fail_device; - - pdev->dev.parent = parent; - - if (cell->pdata_size) { - ret = platform_device_add_data(pdev, - cell->platform_data, cell->pdata_size); - if (ret) - goto fail_res; - } - - ret = mfd_platform_add_cell(pdev, cell); - if (ret) - goto fail_res; - - for (r = 0; r < cell->num_resources; r++) { - res[r].name = cell->resources[r].name; - res[r].flags = cell->resources[r].flags; - - /* Find out base to use */ - if ((cell->resources[r].flags & IORESOURCE_MEM) && mem_base) { - res[r].parent = mem_base; - res[r].start = mem_base->start + - cell->resources[r].start; - res[r].end = mem_base->start + - cell->resources[r].end; - } else if (cell->resources[r].flags & IORESOURCE_IRQ) { - res[r].start = irq_base + - cell->resources[r].start; - res[r].end = irq_base + - cell->resources[r].end; - } else { - res[r].parent = cell->resources[r].parent; - res[r].start = cell->resources[r].start; - res[r].end = cell->resources[r].end; - } - - if (!cell->ignore_resource_conflicts) { - ret = acpi_check_resource_conflict(&res[r]); - if (ret) - goto fail_res; - } - } - - ret = platform_device_add_resources(pdev, res, cell->num_resources); - if (ret) - goto fail_res; - - ret = platform_device_add(pdev); - if (ret) - goto fail_res; - - if (cell->pm_runtime_no_callbacks) - pm_runtime_no_callbacks(&pdev->dev); - - kfree(res); - - return 0; - -fail_res: - kfree(res); -fail_device: - platform_device_put(pdev); -fail_alloc: - return ret; -} - -int mfd_add_devices(struct device *parent, int id, - struct mfd_cell *cells, int n_devs, - struct resource *mem_base, - int irq_base) -{ - int i; - int ret = 0; - atomic_t *cnts; - - /* initialize reference counting for all cells */ - cnts = kcalloc(n_devs, sizeof(*cnts), GFP_KERNEL); - if (!cnts) - return -ENOMEM; - - for (i = 0; i < n_devs; i++) { - atomic_set(&cnts[i], 0); - cells[i].usage_count = &cnts[i]; - ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); - if (ret) - break; - } - - if (ret) - mfd_remove_devices(parent); - - return ret; -} -EXPORT_SYMBOL(mfd_add_devices); - -static int mfd_remove_devices_fn(struct device *dev, void *c) -{ - struct platform_device *pdev = to_platform_device(dev); - const struct mfd_cell *cell = mfd_get_cell(pdev); - atomic_t **usage_count = c; - - /* find the base address of usage_count pointers (for freeing) */ - if (!*usage_count || (cell->usage_count < *usage_count)) - *usage_count = cell->usage_count; - - platform_device_unregister(pdev); - return 0; -} - -void mfd_remove_devices(struct device *parent) -{ - atomic_t *cnts = NULL; - - device_for_each_child(parent, &cnts, mfd_remove_devices_fn); - kfree(cnts); -} -EXPORT_SYMBOL(mfd_remove_devices); - -int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) -{ - struct mfd_cell cell_entry; - struct device *dev; - struct platform_device *pdev; - int i; - - /* fetch the parent cell's device (should already be registered!) */ - dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); - if (!dev) { - printk(KERN_ERR "failed to find device for cell %s\n", cell); - return -ENODEV; - } - pdev = to_platform_device(dev); - memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry)); - - WARN_ON(!cell_entry.enable); - - for (i = 0; i < n_clones; i++) { - cell_entry.name = clones[i]; - /* don't give up if a single call fails; just report error */ - if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) - dev_err(dev, "failed to create platform device '%s'\n", - clones[i]); - } - - return 0; -} -EXPORT_SYMBOL(mfd_clone_cell); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); diff --git a/ANDROID_3.4.5/drivers/mfd/omap-usb-host.c b/ANDROID_3.4.5/drivers/mfd/omap-usb-host.c deleted file mode 100644 index 7e96bb22..00000000 --- a/ANDROID_3.4.5/drivers/mfd/omap-usb-host.c +++ /dev/null @@ -1,874 +0,0 @@ -/** - * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI - * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com - * Author: Keshava Munegowda <keshava_mgowda@ti.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses/>. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/dma-mapping.h> -#include <linux/spinlock.h> -#include <plat/cpu.h> -#include <plat/usb.h> -#include <linux/pm_runtime.h> - -#define USBHS_DRIVER_NAME "usbhs_omap" -#define OMAP_EHCI_DEVICE "ehci-omap" -#define OMAP_OHCI_DEVICE "ohci-omap3" - -/* OMAP USBHOST Register addresses */ - -/* TLL Register Set */ -#define OMAP_USBTLL_REVISION (0x00) -#define OMAP_USBTLL_SYSCONFIG (0x10) -#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_USBTLL_SYSSTATUS (0x14) -#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) - -#define OMAP_USBTLL_IRQSTATUS (0x18) -#define OMAP_USBTLL_IRQENABLE (0x1C) - -#define OMAP_TLL_SHARED_CONF (0x30) -#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) -#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) -#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) -#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) -#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) - -#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) -#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 -#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) -#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) -#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) -#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) -#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) -#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) - -#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0 -#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1 -#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2 -#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3 -#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4 -#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5 -#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6 -#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7 -#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA -#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB - -#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num) -#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num) -#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num) -#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num) -#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num) -#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num) -#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num) -#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) -#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) - -#define OMAP_TLL_CHANNEL_COUNT 3 -#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0) -#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1) -#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2) - -/* UHH Register Set */ -#define OMAP_UHH_REVISION (0x00) -#define OMAP_UHH_SYSCONFIG (0x10) -#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) -#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_UHH_SYSSTATUS (0x14) -#define OMAP_UHH_HOSTCONFIG (0x40) -#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) -#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) -#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) -#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) -#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) -#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) -#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) -#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) -#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) -#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK (1 << 31) - -/* OMAP4-specific defines */ -#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) -#define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) -#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) -#define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) -#define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) - -#define OMAP4_P1_MODE_CLEAR (3 << 16) -#define OMAP4_P1_MODE_TLL (1 << 16) -#define OMAP4_P1_MODE_HSIC (3 << 16) -#define OMAP4_P2_MODE_CLEAR (3 << 18) -#define OMAP4_P2_MODE_TLL (1 << 18) -#define OMAP4_P2_MODE_HSIC (3 << 18) - -#define OMAP_REV2_TLL_CHANNEL_COUNT 2 - -#define OMAP_UHH_DEBUG_CSR (0x44) - -/* Values of UHH_REVISION - Note: these are not given in the TRM */ -#define OMAP_USBHS_REV1 0x00000010 /* OMAP3 */ -#define OMAP_USBHS_REV2 0x50700100 /* OMAP4 */ - -#define is_omap_usbhs_rev1(x) (x->usbhs_rev == OMAP_USBHS_REV1) -#define is_omap_usbhs_rev2(x) (x->usbhs_rev == OMAP_USBHS_REV2) - -#define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY) -#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) -#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) - - -struct usbhs_hcd_omap { - struct clk *xclk60mhsp1_ck; - struct clk *xclk60mhsp2_ck; - struct clk *utmi_p1_fck; - struct clk *usbhost_p1_fck; - struct clk *usbtll_p1_fck; - struct clk *utmi_p2_fck; - struct clk *usbhost_p2_fck; - struct clk *usbtll_p2_fck; - struct clk *init_60m_fclk; - struct clk *ehci_logic_fck; - - void __iomem *uhh_base; - void __iomem *tll_base; - - struct usbhs_omap_platform_data platdata; - - u32 usbhs_rev; - spinlock_t lock; -}; -/*-------------------------------------------------------------------------*/ - -const char usbhs_driver_name[] = USBHS_DRIVER_NAME; -static u64 usbhs_dmamask = DMA_BIT_MASK(32); - -/*-------------------------------------------------------------------------*/ - -static inline void usbhs_write(void __iomem *base, u32 reg, u32 val) -{ - __raw_writel(val, base + reg); -} - -static inline u32 usbhs_read(void __iomem *base, u32 reg) -{ - return __raw_readl(base + reg); -} - -static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val) -{ - __raw_writeb(val, base + reg); -} - -static inline u8 usbhs_readb(void __iomem *base, u8 reg) -{ - return __raw_readb(base + reg); -} - -/*-------------------------------------------------------------------------*/ - -static struct platform_device *omap_usbhs_alloc_child(const char *name, - struct resource *res, int num_resources, void *pdata, - size_t pdata_size, struct device *dev) -{ - struct platform_device *child; - int ret; - - child = platform_device_alloc(name, 0); - - if (!child) { - dev_err(dev, "platform_device_alloc %s failed\n", name); - goto err_end; - } - - ret = platform_device_add_resources(child, res, num_resources); - if (ret) { - dev_err(dev, "platform_device_add_resources failed\n"); - goto err_alloc; - } - - ret = platform_device_add_data(child, pdata, pdata_size); - if (ret) { - dev_err(dev, "platform_device_add_data failed\n"); - goto err_alloc; - } - - child->dev.dma_mask = &usbhs_dmamask; - dma_set_coherent_mask(&child->dev, DMA_BIT_MASK(32)); - child->dev.parent = dev; - - ret = platform_device_add(child); - if (ret) { - dev_err(dev, "platform_device_add failed\n"); - goto err_alloc; - } - - return child; - -err_alloc: - platform_device_put(child); - -err_end: - return NULL; -} - -static int omap_usbhs_alloc_children(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct usbhs_hcd_omap *omap; - struct ehci_hcd_omap_platform_data *ehci_data; - struct ohci_hcd_omap_platform_data *ohci_data; - struct platform_device *ehci; - struct platform_device *ohci; - struct resource *res; - struct resource resources[2]; - int ret; - - omap = platform_get_drvdata(pdev); - ehci_data = omap->platdata.ehci_data; - ohci_data = omap->platdata.ohci_data; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); - if (!res) { - dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n"); - ret = -ENODEV; - goto err_end; - } - resources[0] = *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq"); - if (!res) { - dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n"); - ret = -ENODEV; - goto err_end; - } - resources[1] = *res; - - ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data, - sizeof(*ehci_data), dev); - - if (!ehci) { - dev_err(dev, "omap_usbhs_alloc_child failed\n"); - ret = -ENOMEM; - goto err_end; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci"); - if (!res) { - dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n"); - ret = -ENODEV; - goto err_ehci; - } - resources[0] = *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq"); - if (!res) { - dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n"); - ret = -ENODEV; - goto err_ehci; - } - resources[1] = *res; - - ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data, - sizeof(*ohci_data), dev); - if (!ohci) { - dev_err(dev, "omap_usbhs_alloc_child failed\n"); - ret = -ENOMEM; - goto err_ehci; - } - - return 0; - -err_ehci: - platform_device_unregister(ehci); - -err_end: - return ret; -} - -static bool is_ohci_port(enum usbhs_omap_port_mode pmode) -{ - switch (pmode) { - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: - case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: - case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: - case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: - case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: - return true; - - default: - return false; - } -} - -/* - * convert the port-mode enum to a value we can use in the FSLSMODE - * field of USBTLL_CHANNEL_CONF - */ -static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) -{ - switch (mode) { - case OMAP_USBHS_PORT_MODE_UNUSED: - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: - return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; - - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: - return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM; - - case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: - return OMAP_TLL_FSLSMODE_3PIN_PHY; - - case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: - return OMAP_TLL_FSLSMODE_4PIN_PHY; - - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: - return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0; - - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: - return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM; - - case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: - return OMAP_TLL_FSLSMODE_3PIN_TLL; - - case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: - return OMAP_TLL_FSLSMODE_4PIN_TLL; - - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: - return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0; - - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: - return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM; - default: - pr_warning("Invalid port mode, using default\n"); - return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; - } -} - -static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = dev->platform_data; - unsigned reg; - int i; - - /* Program Common TLL register */ - reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF); - reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON - | OMAP_TLL_SHARED_CONF_USB_DIVRATION); - reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; - reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; - - usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); - - /* Enable channels now */ - for (i = 0; i < tll_channel_count; i++) { - reg = usbhs_read(omap->tll_base, - OMAP_TLL_CHANNEL_CONF(i)); - - if (is_ohci_port(pdata->port_mode[i])) { - reg |= ohci_omap3_fslsmode(pdata->port_mode[i]) - << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; - reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; - } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) { - - /* Disable AutoIdle, BitStuffing and use SDR Mode */ - reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE - | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF - | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); - - } else - continue; - - reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; - usbhs_write(omap->tll_base, - OMAP_TLL_CHANNEL_CONF(i), reg); - - usbhs_writeb(omap->tll_base, - OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); - } -} - -static int usbhs_runtime_resume(struct device *dev) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = &omap->platdata; - unsigned long flags; - - dev_dbg(dev, "usbhs_runtime_resume\n"); - - if (!pdata) { - dev_dbg(dev, "missing platform_data\n"); - return -ENODEV; - } - - spin_lock_irqsave(&omap->lock, flags); - - if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) - clk_enable(omap->ehci_logic_fck); - - if (is_ehci_tll_mode(pdata->port_mode[0])) { - clk_enable(omap->usbhost_p1_fck); - clk_enable(omap->usbtll_p1_fck); - } - if (is_ehci_tll_mode(pdata->port_mode[1])) { - clk_enable(omap->usbhost_p2_fck); - clk_enable(omap->usbtll_p2_fck); - } - clk_enable(omap->utmi_p1_fck); - clk_enable(omap->utmi_p2_fck); - - spin_unlock_irqrestore(&omap->lock, flags); - - return 0; -} - -static int usbhs_runtime_suspend(struct device *dev) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = &omap->platdata; - unsigned long flags; - - dev_dbg(dev, "usbhs_runtime_suspend\n"); - - if (!pdata) { - dev_dbg(dev, "missing platform_data\n"); - return -ENODEV; - } - - spin_lock_irqsave(&omap->lock, flags); - - if (is_ehci_tll_mode(pdata->port_mode[0])) { - clk_disable(omap->usbhost_p1_fck); - clk_disable(omap->usbtll_p1_fck); - } - if (is_ehci_tll_mode(pdata->port_mode[1])) { - clk_disable(omap->usbhost_p2_fck); - clk_disable(omap->usbtll_p2_fck); - } - clk_disable(omap->utmi_p2_fck); - clk_disable(omap->utmi_p1_fck); - - if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) - clk_disable(omap->ehci_logic_fck); - - spin_unlock_irqrestore(&omap->lock, flags); - - return 0; -} - -static void omap_usbhs_init(struct device *dev) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = &omap->platdata; - unsigned long flags; - unsigned reg; - - dev_dbg(dev, "starting TI HSUSB Controller\n"); - - pm_runtime_get_sync(dev); - spin_lock_irqsave(&omap->lock, flags); - - omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); - dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); - - reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); - /* setup ULPI bypass and burst configurations */ - reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); - reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; - reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; - - if (is_omap_usbhs_rev1(omap)) { - if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; - - /* Bypass the TLL module for PHY mode operation */ - if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { - dev_dbg(dev, "OMAP3 ES version <= ES2.1\n"); - if (is_ehci_phy_mode(pdata->port_mode[0]) || - is_ehci_phy_mode(pdata->port_mode[1]) || - is_ehci_phy_mode(pdata->port_mode[2])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; - } else { - dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); - if (is_ehci_phy_mode(pdata->port_mode[0])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - if (is_ehci_phy_mode(pdata->port_mode[1])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - if (is_ehci_phy_mode(pdata->port_mode[2])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - } - } else if (is_omap_usbhs_rev2(omap)) { - /* Clear port mode fields for PHY mode*/ - reg &= ~OMAP4_P1_MODE_CLEAR; - reg &= ~OMAP4_P2_MODE_CLEAR; - - if (is_ehci_tll_mode(pdata->port_mode[0]) || - (is_ohci_port(pdata->port_mode[0]))) - reg |= OMAP4_P1_MODE_TLL; - else if (is_ehci_hsic_mode(pdata->port_mode[0])) - reg |= OMAP4_P1_MODE_HSIC; - - if (is_ehci_tll_mode(pdata->port_mode[1]) || - (is_ohci_port(pdata->port_mode[1]))) - reg |= OMAP4_P2_MODE_TLL; - else if (is_ehci_hsic_mode(pdata->port_mode[1])) - reg |= OMAP4_P2_MODE_HSIC; - } - - usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); - dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); - - if (is_ehci_tll_mode(pdata->port_mode[0]) || - is_ehci_tll_mode(pdata->port_mode[1]) || - is_ehci_tll_mode(pdata->port_mode[2]) || - (is_ohci_port(pdata->port_mode[0])) || - (is_ohci_port(pdata->port_mode[1])) || - (is_ohci_port(pdata->port_mode[2]))) { - - /* Enable UTMI mode for required TLL channels */ - if (is_omap_usbhs_rev2(omap)) - usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); - else - usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); - } - - spin_unlock_irqrestore(&omap->lock, flags); - pm_runtime_put_sync(dev); -} - - -/** - * usbhs_omap_probe - initialize TI-based HCDs - * - * Allocates basic resources for this USB host controller. - */ -static int __devinit usbhs_omap_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct usbhs_omap_platform_data *pdata = dev->platform_data; - struct usbhs_hcd_omap *omap; - struct resource *res; - int ret = 0; - int i; - - if (!pdata) { - dev_err(dev, "Missing platform data\n"); - ret = -ENOMEM; - goto end_probe; - } - - omap = kzalloc(sizeof(*omap), GFP_KERNEL); - if (!omap) { - dev_err(dev, "Memory allocation failed\n"); - ret = -ENOMEM; - goto end_probe; - } - - spin_lock_init(&omap->lock); - - for (i = 0; i < OMAP3_HS_USB_PORTS; i++) - omap->platdata.port_mode[i] = pdata->port_mode[i]; - - omap->platdata.ehci_data = pdata->ehci_data; - omap->platdata.ohci_data = pdata->ohci_data; - - pm_runtime_enable(dev); - - - for (i = 0; i < OMAP3_HS_USB_PORTS; i++) - if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || - is_ehci_hsic_mode(i)) { - omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); - if (IS_ERR(omap->ehci_logic_fck)) { - ret = PTR_ERR(omap->ehci_logic_fck); - dev_warn(dev, "ehci_logic_fck failed:%d\n", - ret); - } - break; - } - - omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); - if (IS_ERR(omap->utmi_p1_fck)) { - ret = PTR_ERR(omap->utmi_p1_fck); - dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); - goto err_end; - } - - omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); - if (IS_ERR(omap->xclk60mhsp1_ck)) { - ret = PTR_ERR(omap->xclk60mhsp1_ck); - dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); - goto err_utmi_p1_fck; - } - - omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); - if (IS_ERR(omap->utmi_p2_fck)) { - ret = PTR_ERR(omap->utmi_p2_fck); - dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); - goto err_xclk60mhsp1_ck; - } - - omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); - if (IS_ERR(omap->xclk60mhsp2_ck)) { - ret = PTR_ERR(omap->xclk60mhsp2_ck); - dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); - goto err_utmi_p2_fck; - } - - omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); - if (IS_ERR(omap->usbhost_p1_fck)) { - ret = PTR_ERR(omap->usbhost_p1_fck); - dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); - goto err_xclk60mhsp2_ck; - } - - omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); - if (IS_ERR(omap->usbtll_p1_fck)) { - ret = PTR_ERR(omap->usbtll_p1_fck); - dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); - goto err_usbhost_p1_fck; - } - - omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); - if (IS_ERR(omap->usbhost_p2_fck)) { - ret = PTR_ERR(omap->usbhost_p2_fck); - dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); - goto err_usbtll_p1_fck; - } - - omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); - if (IS_ERR(omap->usbtll_p2_fck)) { - ret = PTR_ERR(omap->usbtll_p2_fck); - dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); - goto err_usbhost_p2_fck; - } - - omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); - if (IS_ERR(omap->init_60m_fclk)) { - ret = PTR_ERR(omap->init_60m_fclk); - dev_err(dev, "init_60m_fclk failed error:%d\n", ret); - goto err_usbtll_p2_fck; - } - - if (is_ehci_phy_mode(pdata->port_mode[0])) { - /* for OMAP3 , the clk set paretn fails */ - ret = clk_set_parent(omap->utmi_p1_fck, - omap->xclk60mhsp1_ck); - if (ret != 0) - dev_err(dev, "xclk60mhsp1_ck set parent" - "failed error:%d\n", ret); - } else if (is_ehci_tll_mode(pdata->port_mode[0])) { - ret = clk_set_parent(omap->utmi_p1_fck, - omap->init_60m_fclk); - if (ret != 0) - dev_err(dev, "init_60m_fclk set parent" - "failed error:%d\n", ret); - } - - if (is_ehci_phy_mode(pdata->port_mode[1])) { - ret = clk_set_parent(omap->utmi_p2_fck, - omap->xclk60mhsp2_ck); - if (ret != 0) - dev_err(dev, "xclk60mhsp2_ck set parent" - "failed error:%d\n", ret); - } else if (is_ehci_tll_mode(pdata->port_mode[1])) { - ret = clk_set_parent(omap->utmi_p2_fck, - omap->init_60m_fclk); - if (ret != 0) - dev_err(dev, "init_60m_fclk set parent" - "failed error:%d\n", ret); - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); - if (!res) { - dev_err(dev, "UHH EHCI get resource failed\n"); - ret = -ENODEV; - goto err_init_60m_fclk; - } - - omap->uhh_base = ioremap(res->start, resource_size(res)); - if (!omap->uhh_base) { - dev_err(dev, "UHH ioremap failed\n"); - ret = -ENOMEM; - goto err_init_60m_fclk; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); - if (!res) { - dev_err(dev, "UHH EHCI get resource failed\n"); - ret = -ENODEV; - goto err_tll; - } - - omap->tll_base = ioremap(res->start, resource_size(res)); - if (!omap->tll_base) { - dev_err(dev, "TLL ioremap failed\n"); - ret = -ENOMEM; - goto err_tll; - } - - platform_set_drvdata(pdev, omap); - - omap_usbhs_init(dev); - ret = omap_usbhs_alloc_children(pdev); - if (ret) { - dev_err(dev, "omap_usbhs_alloc_children failed\n"); - goto err_alloc; - } - - goto end_probe; - -err_alloc: - iounmap(omap->tll_base); - -err_tll: - iounmap(omap->uhh_base); - -err_init_60m_fclk: - clk_put(omap->init_60m_fclk); - -err_usbtll_p2_fck: - clk_put(omap->usbtll_p2_fck); - -err_usbhost_p2_fck: - clk_put(omap->usbhost_p2_fck); - -err_usbtll_p1_fck: - clk_put(omap->usbtll_p1_fck); - -err_usbhost_p1_fck: - clk_put(omap->usbhost_p1_fck); - -err_xclk60mhsp2_ck: - clk_put(omap->xclk60mhsp2_ck); - -err_utmi_p2_fck: - clk_put(omap->utmi_p2_fck); - -err_xclk60mhsp1_ck: - clk_put(omap->xclk60mhsp1_ck); - -err_utmi_p1_fck: - clk_put(omap->utmi_p1_fck); - -err_end: - clk_put(omap->ehci_logic_fck); - pm_runtime_disable(dev); - kfree(omap); - -end_probe: - return ret; -} - -/** - * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs - * @pdev: USB Host Controller being removed - * - * Reverses the effect of usbhs_omap_probe(). - */ -static int __devexit usbhs_omap_remove(struct platform_device *pdev) -{ - struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); - - iounmap(omap->tll_base); - iounmap(omap->uhh_base); - clk_put(omap->init_60m_fclk); - clk_put(omap->usbtll_p2_fck); - clk_put(omap->usbhost_p2_fck); - clk_put(omap->usbtll_p1_fck); - clk_put(omap->usbhost_p1_fck); - clk_put(omap->xclk60mhsp2_ck); - clk_put(omap->utmi_p2_fck); - clk_put(omap->xclk60mhsp1_ck); - clk_put(omap->utmi_p1_fck); - clk_put(omap->ehci_logic_fck); - pm_runtime_disable(&pdev->dev); - kfree(omap); - - return 0; -} - -static const struct dev_pm_ops usbhsomap_dev_pm_ops = { - .runtime_suspend = usbhs_runtime_suspend, - .runtime_resume = usbhs_runtime_resume, -}; - -static struct platform_driver usbhs_omap_driver = { - .driver = { - .name = (char *)usbhs_driver_name, - .owner = THIS_MODULE, - .pm = &usbhsomap_dev_pm_ops, - }, - .remove = __exit_p(usbhs_omap_remove), -}; - -MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>"); -MODULE_ALIAS("platform:" USBHS_DRIVER_NAME); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI"); - -static int __init omap_usbhs_drvinit(void) -{ - return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe); -} - -/* - * init before ehci and ohci drivers; - * The usbhs core driver should be initialized much before - * the omap ehci and ohci probe functions are called. - */ -fs_initcall(omap_usbhs_drvinit); - -static void __exit omap_usbhs_drvexit(void) -{ - platform_driver_unregister(&usbhs_omap_driver); -} -module_exit(omap_usbhs_drvexit); diff --git a/ANDROID_3.4.5/drivers/mfd/pcf50633-adc.c b/ANDROID_3.4.5/drivers/mfd/pcf50633-adc.c deleted file mode 100644 index 3927c17e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pcf50633-adc.c +++ /dev/null @@ -1,258 +0,0 @@ -/* NXP PCF50633 ADC Driver - * - * (C) 2006-2008 by Openmoko, Inc. - * Author: Balaji Rao <balajirrao@openmoko.org> - * All rights reserved. - * - * Broken down from monstrous PCF50633 driver mainly by - * Harald Welte, Andy Green and Werner Almesberger - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * NOTE: This driver does not yet support subtractive ADC mode, which means - * you can do only one measurement per read request. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/completion.h> - -#include <linux/mfd/pcf50633/core.h> -#include <linux/mfd/pcf50633/adc.h> - -struct pcf50633_adc_request { - int mux; - int avg; - void (*callback)(struct pcf50633 *, void *, int); - void *callback_param; -}; - -struct pcf50633_adc_sync_request { - int result; - struct completion completion; -}; - -#define PCF50633_MAX_ADC_FIFO_DEPTH 8 - -struct pcf50633_adc { - struct pcf50633 *pcf; - - /* Private stuff */ - struct pcf50633_adc_request *queue[PCF50633_MAX_ADC_FIFO_DEPTH]; - int queue_head; - int queue_tail; - struct mutex queue_mutex; -}; - -static inline struct pcf50633_adc *__to_adc(struct pcf50633 *pcf) -{ - return platform_get_drvdata(pcf->adc_pdev); -} - -static void adc_setup(struct pcf50633 *pcf, int channel, int avg) -{ - channel &= PCF50633_ADCC1_ADCMUX_MASK; - - /* kill ratiometric, but enable ACCSW biasing */ - pcf50633_reg_write(pcf, PCF50633_REG_ADCC2, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_ADCC3, 0x01); - - /* start ADC conversion on selected channel */ - pcf50633_reg_write(pcf, PCF50633_REG_ADCC1, channel | avg | - PCF50633_ADCC1_ADCSTART | PCF50633_ADCC1_RES_10BIT); -} - -static void trigger_next_adc_job_if_any(struct pcf50633 *pcf) -{ - struct pcf50633_adc *adc = __to_adc(pcf); - int head; - - head = adc->queue_head; - - if (!adc->queue[head]) - return; - - adc_setup(pcf, adc->queue[head]->mux, adc->queue[head]->avg); -} - -static int -adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req) -{ - struct pcf50633_adc *adc = __to_adc(pcf); - int head, tail; - - mutex_lock(&adc->queue_mutex); - - head = adc->queue_head; - tail = adc->queue_tail; - - if (adc->queue[tail]) { - mutex_unlock(&adc->queue_mutex); - dev_err(pcf->dev, "ADC queue is full, dropping request\n"); - return -EBUSY; - } - - adc->queue[tail] = req; - if (head == tail) - trigger_next_adc_job_if_any(pcf); - adc->queue_tail = (tail + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1); - - mutex_unlock(&adc->queue_mutex); - - return 0; -} - -static void pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, - int result) -{ - struct pcf50633_adc_sync_request *req = param; - - req->result = result; - complete(&req->completion); -} - -int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg) -{ - struct pcf50633_adc_sync_request req; - int ret; - - init_completion(&req.completion); - - ret = pcf50633_adc_async_read(pcf, mux, avg, - pcf50633_adc_sync_read_callback, &req); - if (ret) - return ret; - - wait_for_completion(&req.completion); - - return req.result; -} -EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read); - -int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg, - void (*callback)(struct pcf50633 *, void *, int), - void *callback_param) -{ - struct pcf50633_adc_request *req; - - /* req is freed when the result is ready, in interrupt handler */ - req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - - req->mux = mux; - req->avg = avg; - req->callback = callback; - req->callback_param = callback_param; - - return adc_enqueue_request(pcf, req); -} -EXPORT_SYMBOL_GPL(pcf50633_adc_async_read); - -static int adc_result(struct pcf50633 *pcf) -{ - u8 adcs1, adcs3; - u16 result; - - adcs1 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS1); - adcs3 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS3); - result = (adcs1 << 2) | (adcs3 & PCF50633_ADCS3_ADCDAT1L_MASK); - - dev_dbg(pcf->dev, "adc result = %d\n", result); - - return result; -} - -static void pcf50633_adc_irq(int irq, void *data) -{ - struct pcf50633_adc *adc = data; - struct pcf50633 *pcf = adc->pcf; - struct pcf50633_adc_request *req; - int head, res; - - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - - req = adc->queue[head]; - if (WARN_ON(!req)) { - dev_err(pcf->dev, "pcf50633-adc irq: ADC queue empty!\n"); - mutex_unlock(&adc->queue_mutex); - return; - } - adc->queue[head] = NULL; - adc->queue_head = (head + 1) & - (PCF50633_MAX_ADC_FIFO_DEPTH - 1); - - res = adc_result(pcf); - trigger_next_adc_job_if_any(pcf); - - mutex_unlock(&adc->queue_mutex); - - req->callback(pcf, req->callback_param, res); - kfree(req); -} - -static int __devinit pcf50633_adc_probe(struct platform_device *pdev) -{ - struct pcf50633_adc *adc; - - adc = kzalloc(sizeof(*adc), GFP_KERNEL); - if (!adc) - return -ENOMEM; - - adc->pcf = dev_to_pcf50633(pdev->dev.parent); - platform_set_drvdata(pdev, adc); - - pcf50633_register_irq(adc->pcf, PCF50633_IRQ_ADCRDY, - pcf50633_adc_irq, adc); - - mutex_init(&adc->queue_mutex); - - return 0; -} - -static int __devexit pcf50633_adc_remove(struct platform_device *pdev) -{ - struct pcf50633_adc *adc = platform_get_drvdata(pdev); - int i, head; - - pcf50633_free_irq(adc->pcf, PCF50633_IRQ_ADCRDY); - - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - - if (WARN_ON(adc->queue[head])) - dev_err(adc->pcf->dev, - "adc driver removed with request pending\n"); - - for (i = 0; i < PCF50633_MAX_ADC_FIFO_DEPTH; i++) - kfree(adc->queue[i]); - - mutex_unlock(&adc->queue_mutex); - kfree(adc); - - return 0; -} - -static struct platform_driver pcf50633_adc_driver = { - .driver = { - .name = "pcf50633-adc", - }, - .probe = pcf50633_adc_probe, - .remove = __devexit_p(pcf50633_adc_remove), -}; - -module_platform_driver(pcf50633_adc_driver); - -MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); -MODULE_DESCRIPTION("PCF50633 adc driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pcf50633-adc"); - diff --git a/ANDROID_3.4.5/drivers/mfd/pcf50633-core.c b/ANDROID_3.4.5/drivers/mfd/pcf50633-core.c deleted file mode 100644 index 189c2f07..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pcf50633-core.c +++ /dev/null @@ -1,340 +0,0 @@ -/* NXP PCF50633 Power Management Unit (PMU) driver - * - * (C) 2006-2008 by Openmoko, Inc. - * Author: Harald Welte <laforge@openmoko.org> - * Balaji Rao <balajirrao@openmoko.org> - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/sysfs.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/workqueue.h> -#include <linux/platform_device.h> -#include <linux/i2c.h> -#include <linux/pm.h> -#include <linux/slab.h> -#include <linux/regmap.h> -#include <linux/err.h> - -#include <linux/mfd/pcf50633/core.h> - -/* Read a block of up to 32 regs */ -int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, - int nr_regs, u8 *data) -{ - int ret; - - ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs); - if (ret != 0) - return ret; - - return nr_regs; -} -EXPORT_SYMBOL_GPL(pcf50633_read_block); - -/* Write a block of up to 32 regs */ -int pcf50633_write_block(struct pcf50633 *pcf , u8 reg, - int nr_regs, u8 *data) -{ - return regmap_raw_write(pcf->regmap, reg, data, nr_regs); -} -EXPORT_SYMBOL_GPL(pcf50633_write_block); - -u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) -{ - unsigned int val; - int ret; - - ret = regmap_read(pcf->regmap, reg, &val); - if (ret < 0) - return -1; - - return val; -} -EXPORT_SYMBOL_GPL(pcf50633_reg_read); - -int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) -{ - return regmap_write(pcf->regmap, reg, val); -} -EXPORT_SYMBOL_GPL(pcf50633_reg_write); - -int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) -{ - return regmap_update_bits(pcf->regmap, reg, mask, val); -} -EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); - -int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) -{ - return regmap_update_bits(pcf->regmap, reg, val, 0); -} -EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); - -/* sysfs attributes */ -static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct pcf50633 *pcf = dev_get_drvdata(dev); - u8 dump[16]; - int n, n1, idx = 0; - char *buf1 = buf; - static u8 address_no_read[] = { /* must be ascending */ - PCF50633_REG_INT1, - PCF50633_REG_INT2, - PCF50633_REG_INT3, - PCF50633_REG_INT4, - PCF50633_REG_INT5, - 0 /* terminator */ - }; - - for (n = 0; n < 256; n += sizeof(dump)) { - for (n1 = 0; n1 < sizeof(dump); n1++) - if (n == address_no_read[idx]) { - idx++; - dump[n1] = 0x00; - } else - dump[n1] = pcf50633_reg_read(pcf, n + n1); - - hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0); - buf1 += strlen(buf1); - *buf1++ = '\n'; - *buf1 = '\0'; - } - - return buf1 - buf; -} -static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL); - -static ssize_t show_resume_reason(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pcf50633 *pcf = dev_get_drvdata(dev); - int n; - - n = sprintf(buf, "%02x%02x%02x%02x%02x\n", - pcf->resume_reason[0], - pcf->resume_reason[1], - pcf->resume_reason[2], - pcf->resume_reason[3], - pcf->resume_reason[4]); - - return n; -} -static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL); - -static struct attribute *pcf_sysfs_entries[] = { - &dev_attr_dump_regs.attr, - &dev_attr_resume_reason.attr, - NULL, -}; - -static struct attribute_group pcf_attr_group = { - .name = NULL, /* put in device directory */ - .attrs = pcf_sysfs_entries, -}; - -static void -pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, - struct platform_device **pdev) -{ - int ret; - - *pdev = platform_device_alloc(name, -1); - if (!*pdev) { - dev_err(pcf->dev, "Falied to allocate %s\n", name); - return; - } - - (*pdev)->dev.parent = pcf->dev; - - ret = platform_device_add(*pdev); - if (ret) { - dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret); - platform_device_put(*pdev); - *pdev = NULL; - } -} - -#ifdef CONFIG_PM_SLEEP -static int pcf50633_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct pcf50633 *pcf = i2c_get_clientdata(client); - - return pcf50633_irq_suspend(pcf); -} - -static int pcf50633_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct pcf50633 *pcf = i2c_get_clientdata(client); - - return pcf50633_irq_resume(pcf); -} -#endif - -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, - const struct i2c_device_id *ids) -{ - struct pcf50633 *pcf; - struct pcf50633_platform_data *pdata = client->dev.platform_data; - int i, ret; - int version, variant; - - if (!client->irq) { - dev_err(&client->dev, "Missing IRQ\n"); - return -ENOENT; - } - - pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); - if (!pcf) - return -ENOMEM; - - pcf->pdata = pdata; - - 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); - pcf->dev = &client->dev; - - version = pcf50633_reg_read(pcf, 0); - variant = pcf50633_reg_read(pcf, 1); - if (version < 0 || variant < 0) { - dev_err(pcf->dev, "Unable to probe pcf50633\n"); - ret = -ENODEV; - goto err_regmap; - } - - dev_info(pcf->dev, "Probed device version %d variant %d\n", - version, variant); - - pcf50633_irq_init(pcf, client->irq); - - /* Create sub devices */ - pcf50633_client_dev_register(pcf, "pcf50633-input", - &pcf->input_pdev); - pcf50633_client_dev_register(pcf, "pcf50633-rtc", - &pcf->rtc_pdev); - pcf50633_client_dev_register(pcf, "pcf50633-mbc", - &pcf->mbc_pdev); - pcf50633_client_dev_register(pcf, "pcf50633-adc", - &pcf->adc_pdev); - pcf50633_client_dev_register(pcf, "pcf50633-backlight", - &pcf->bl_pdev); - - - for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { - struct platform_device *pdev; - - pdev = platform_device_alloc("pcf50633-regltr", i); - if (!pdev) { - dev_err(pcf->dev, "Cannot create regulator %d\n", i); - continue; - } - - pdev->dev.parent = pcf->dev; - platform_device_add_data(pdev, &pdata->reg_init_data[i], - sizeof(pdata->reg_init_data[i])); - pcf->regulator_pdev[i] = pdev; - - platform_device_add(pdev); - } - - ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group); - if (ret) - dev_err(pcf->dev, "error creating sysfs entries\n"); - - if (pdata->probe_done) - pdata->probe_done(pcf); - - return 0; - -err_regmap: - regmap_exit(pcf->regmap); -err_free: - kfree(pcf); - - return ret; -} - -static int __devexit pcf50633_remove(struct i2c_client *client) -{ - struct pcf50633 *pcf = i2c_get_clientdata(client); - int i; - - sysfs_remove_group(&client->dev.kobj, &pcf_attr_group); - pcf50633_irq_free(pcf); - - platform_device_unregister(pcf->input_pdev); - platform_device_unregister(pcf->rtc_pdev); - platform_device_unregister(pcf->mbc_pdev); - platform_device_unregister(pcf->adc_pdev); - platform_device_unregister(pcf->bl_pdev); - - for (i = 0; i < PCF50633_NUM_REGULATORS; i++) - platform_device_unregister(pcf->regulator_pdev[i]); - - regmap_exit(pcf->regmap); - kfree(pcf); - - return 0; -} - -static const struct i2c_device_id pcf50633_id_table[] = { - {"pcf50633", 0x73}, - {/* end of list */} -}; -MODULE_DEVICE_TABLE(i2c, pcf50633_id_table); - -static struct i2c_driver pcf50633_driver = { - .driver = { - .name = "pcf50633", - .pm = &pcf50633_pm, - }, - .id_table = pcf50633_id_table, - .probe = pcf50633_probe, - .remove = __devexit_p(pcf50633_remove), -}; - -static int __init pcf50633_init(void) -{ - return i2c_add_driver(&pcf50633_driver); -} - -static void __exit pcf50633_exit(void) -{ - i2c_del_driver(&pcf50633_driver); -} - -MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 PMU"); -MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); -MODULE_LICENSE("GPL"); - -subsys_initcall(pcf50633_init); -module_exit(pcf50633_exit); diff --git a/ANDROID_3.4.5/drivers/mfd/pcf50633-gpio.c b/ANDROID_3.4.5/drivers/mfd/pcf50633-gpio.c deleted file mode 100644 index d02ddf2e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pcf50633-gpio.c +++ /dev/null @@ -1,96 +0,0 @@ -/* NXP PCF50633 GPIO Driver - * - * (C) 2006-2008 by Openmoko, Inc. - * Author: Balaji Rao <balajirrao@openmoko.org> - * All rights reserved. - * - * Broken down from monstrous PCF50633 driver mainly by - * Harald Welte, Andy Green and Werner Almesberger - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> - -#include <linux/mfd/pcf50633/core.h> -#include <linux/mfd/pcf50633/gpio.h> -#include <linux/mfd/pcf50633/pmic.h> - -static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = { - [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT, - [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT, - [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT, - [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT, - [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT, - [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT, - [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT, - [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT, - [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT, - [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT, - [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT, -}; - -int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val) -{ - u8 reg; - - reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; - - return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val); -} -EXPORT_SYMBOL_GPL(pcf50633_gpio_set); - -u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio) -{ - u8 reg, val; - - reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; - val = pcf50633_reg_read(pcf, reg) & 0x07; - - return val; -} -EXPORT_SYMBOL_GPL(pcf50633_gpio_get); - -int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert) -{ - u8 val, reg; - - reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; - val = !!invert << 3; - - return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val); -} -EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set); - -int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio) -{ - u8 reg, val; - - reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; - val = pcf50633_reg_read(pcf, reg); - - return val & (1 << 3); -} -EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get); - -int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf, - int gpio, int regulator, int on) -{ - u8 reg, val, mask; - - /* the *ENA register is always one after the *OUT register */ - reg = pcf50633_regulator_registers[regulator] + 1; - - val = !!on << (gpio - PCF50633_GPIO1); - mask = 1 << (gpio - PCF50633_GPIO1); - - return pcf50633_reg_set_bit_mask(pcf, reg, mask, val); -} -EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/pcf50633-irq.c b/ANDROID_3.4.5/drivers/mfd/pcf50633-irq.c deleted file mode 100644 index 498286cb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pcf50633-irq.c +++ /dev/null @@ -1,314 +0,0 @@ -/* NXP PCF50633 Power Management Unit (PMU) driver - * - * (C) 2006-2008 by Openmoko, Inc. - * Author: Harald Welte <laforge@openmoko.org> - * Balaji Rao <balajirrao@openmoko.org> - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/mutex.h> -#include <linux/export.h> -#include <linux/slab.h> - -#include <linux/mfd/pcf50633/core.h> -#include <linux/mfd/pcf50633/mbc.h> - -int pcf50633_register_irq(struct pcf50633 *pcf, int irq, - void (*handler) (int, void *), void *data) -{ - if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler) - return -EINVAL; - - if (WARN_ON(pcf->irq_handler[irq].handler)) - return -EBUSY; - - mutex_lock(&pcf->lock); - pcf->irq_handler[irq].handler = handler; - pcf->irq_handler[irq].data = data; - mutex_unlock(&pcf->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(pcf50633_register_irq); - -int pcf50633_free_irq(struct pcf50633 *pcf, int irq) -{ - if (irq < 0 || irq >= PCF50633_NUM_IRQ) - return -EINVAL; - - mutex_lock(&pcf->lock); - pcf->irq_handler[irq].handler = NULL; - mutex_unlock(&pcf->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(pcf50633_free_irq); - -static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) -{ - u8 reg, bit; - int ret = 0, idx; - - idx = irq >> 3; - reg = PCF50633_REG_INT1M + idx; - bit = 1 << (irq & 0x07); - - pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0); - - mutex_lock(&pcf->lock); - - if (mask) - pcf->mask_regs[idx] |= bit; - else - pcf->mask_regs[idx] &= ~bit; - - mutex_unlock(&pcf->lock); - - return ret; -} - -int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) -{ - dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); - - return __pcf50633_irq_mask_set(pcf, irq, 1); -} -EXPORT_SYMBOL_GPL(pcf50633_irq_mask); - -int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq) -{ - dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); - - return __pcf50633_irq_mask_set(pcf, irq, 0); -} -EXPORT_SYMBOL_GPL(pcf50633_irq_unmask); - -int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq) -{ - u8 reg, bits; - - reg = irq >> 3; - bits = 1 << (irq & 0x07); - - return pcf->mask_regs[reg] & bits; -} -EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get); - -static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq) -{ - if (pcf->irq_handler[irq].handler) - pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data); -} - -/* Maximum amount of time ONKEY is held before emergency action is taken */ -#define PCF50633_ONKEY1S_TIMEOUT 8 - -static irqreturn_t pcf50633_irq(int irq, void *data) -{ - struct pcf50633 *pcf = data; - int ret, i, j; - u8 pcf_int[5], chgstat; - - /* Read the 5 INT regs in one transaction */ - ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, - ARRAY_SIZE(pcf_int), pcf_int); - if (ret != ARRAY_SIZE(pcf_int)) { - dev_err(pcf->dev, "Error reading INT registers\n"); - - /* - * If this doesn't ACK the interrupt to the chip, we'll be - * called once again as we're level triggered. - */ - goto out; - } - - /* defeat 8s death from lowsys on A5 */ - pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04); - - /* We immediately read the usb and adapter status. We thus make sure - * only of USBINS/USBREM IRQ handlers are called */ - if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { - chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); - if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~PCF50633_INT1_USBREM; - else - pcf_int[0] &= ~PCF50633_INT1_USBINS; - } - - /* Make sure only one of ADPINS or ADPREM is set */ - if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { - chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); - if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~PCF50633_INT1_ADPREM; - else - pcf_int[0] &= ~PCF50633_INT1_ADPINS; - } - - dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " - "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], - pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); - - /* Some revisions of the chip don't have a 8s standby mode on - * ONKEY1S press. We try to manually do it in such cases. */ - if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) { - dev_info(pcf->dev, "ONKEY1S held for %d secs\n", - pcf->onkey1s_held); - if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT) - if (pcf->pdata->force_shutdown) - pcf->pdata->force_shutdown(pcf); - } - - if (pcf_int[2] & PCF50633_INT3_ONKEY1S) { - dev_info(pcf->dev, "ONKEY1S held\n"); - pcf->onkey1s_held = 1 ; - - /* Unmask IRQ_SECOND */ - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, - PCF50633_INT1_SECOND); - - /* Unmask IRQ_ONKEYR */ - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M, - PCF50633_INT2_ONKEYR); - } - - if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) { - pcf->onkey1s_held = 0; - - /* Mask SECOND and ONKEYR interrupts */ - if (pcf->mask_regs[0] & PCF50633_INT1_SECOND) - pcf50633_reg_set_bit_mask(pcf, - PCF50633_REG_INT1M, - PCF50633_INT1_SECOND, - PCF50633_INT1_SECOND); - - if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR) - pcf50633_reg_set_bit_mask(pcf, - PCF50633_REG_INT2M, - PCF50633_INT2_ONKEYR, - PCF50633_INT2_ONKEYR); - } - - /* Have we just resumed ? */ - if (pcf->is_suspended) { - pcf->is_suspended = 0; - - /* Set the resume reason filtering out non resumers */ - for (i = 0; i < ARRAY_SIZE(pcf_int); i++) - pcf->resume_reason[i] = pcf_int[i] & - pcf->pdata->resumers[i]; - - /* Make sure we don't pass on any ONKEY events to - * userspace now */ - pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF); - } - - for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { - /* Unset masked interrupts */ - pcf_int[i] &= ~pcf->mask_regs[i]; - - for (j = 0; j < 8 ; j++) - if (pcf_int[i] & (1 << j)) - pcf50633_irq_call_handler(pcf, (i * 8) + j); - } - -out: - return IRQ_HANDLED; -} - -#ifdef CONFIG_PM - -int pcf50633_irq_suspend(struct pcf50633 *pcf) -{ - int ret; - int i; - u8 res[5]; - - - /* Make sure our interrupt handlers are not called - * henceforth */ - disable_irq(pcf->irq); - - /* Save the masks */ - ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(pcf->suspend_irq_masks), - pcf->suspend_irq_masks); - if (ret < 0) { - dev_err(pcf->dev, "error saving irq masks\n"); - goto out; - } - - /* Write wakeup irq masks */ - for (i = 0; i < ARRAY_SIZE(res); i++) - res[i] = ~pcf->pdata->resumers[i]; - - ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(res), &res[0]); - if (ret < 0) { - dev_err(pcf->dev, "error writing wakeup irq masks\n"); - goto out; - } - - pcf->is_suspended = 1; - -out: - return ret; -} - -int pcf50633_irq_resume(struct pcf50633 *pcf) -{ - int ret; - - /* Write the saved mask registers */ - ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(pcf->suspend_irq_masks), - pcf->suspend_irq_masks); - if (ret < 0) - dev_err(pcf->dev, "Error restoring saved suspend masks\n"); - - enable_irq(pcf->irq); - - return ret; -} - -#endif - -int pcf50633_irq_init(struct pcf50633 *pcf, int irq) -{ - int ret; - - pcf->irq = irq; - - /* Enable all interrupts except RTC SECOND */ - pcf->mask_regs[0] = 0x80; - pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]); - pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); - - ret = request_threaded_irq(irq, NULL, pcf50633_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "pcf50633", pcf); - - if (ret) - dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); - - if (enable_irq_wake(irq) < 0) - dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source" - "in this hardware revision", irq); - - return ret; -} - -void pcf50633_irq_free(struct pcf50633 *pcf) -{ - free_irq(pcf->irq, pcf); -} diff --git a/ANDROID_3.4.5/drivers/mfd/pm8921-core.c b/ANDROID_3.4.5/drivers/mfd/pm8921-core.c deleted file mode 100644 index e873b157..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pm8921-core.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * 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. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/msm_ssbi.h> -#include <linux/mfd/core.h> -#include <linux/mfd/pm8xxx/pm8921.h> -#include <linux/mfd/pm8xxx/core.h> - -#define REG_HWREV 0x002 /* PMIC4 revision */ -#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */ - -struct pm8921 { - struct device *dev; - struct pm_irq_chip *irq_chip; -}; - -static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) -{ - const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); - const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - - return msm_ssbi_read(pmic->dev->parent, addr, val, 1); -} - -static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) -{ - const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); - const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - - return msm_ssbi_write(pmic->dev->parent, addr, &val, 1); -} - -static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf, - int cnt) -{ - const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); - const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - - return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt); -} - -static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, - int cnt) -{ - const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); - const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - - return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt); -} - -static int pm8921_read_irq_stat(const struct device *dev, int irq) -{ - const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); - const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - - return pm8xxx_get_irq_stat(pmic->irq_chip, irq); -} - -static struct pm8xxx_drvdata pm8921_drvdata = { - .pmic_readb = pm8921_readb, - .pmic_writeb = pm8921_writeb, - .pmic_read_buf = pm8921_read_buf, - .pmic_write_buf = pm8921_write_buf, - .pmic_read_irq_stat = pm8921_read_irq_stat, -}; - -static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data - *pdata, - struct pm8921 *pmic, - u32 rev) -{ - int ret = 0, irq_base = 0; - struct pm_irq_chip *irq_chip; - - if (pdata->irq_pdata) { - pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS; - pdata->irq_pdata->irq_cdata.rev = rev; - irq_base = pdata->irq_pdata->irq_base; - irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); - - if (IS_ERR(irq_chip)) { - pr_err("Failed to init interrupts ret=%ld\n", - PTR_ERR(irq_chip)); - return PTR_ERR(irq_chip); - } - pmic->irq_chip = irq_chip; - } - return ret; -} - -static int __devinit pm8921_probe(struct platform_device *pdev) -{ - const struct pm8921_platform_data *pdata = pdev->dev.platform_data; - struct pm8921 *pmic; - int rc; - u8 val; - u32 rev; - - if (!pdata) { - pr_err("missing platform data\n"); - return -EINVAL; - } - - pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL); - if (!pmic) { - pr_err("Cannot alloc pm8921 struct\n"); - return -ENOMEM; - } - - /* Read PMIC chip revision */ - rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val)); - if (rc) { - pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); - goto err_read_rev; - } - pr_info("PMIC revision 1: %02X\n", val); - rev = val; - - /* Read PMIC chip revision 2 */ - rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); - if (rc) { - pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", - REG_HWREV_2, rc); - goto err_read_rev; - } - pr_info("PMIC revision 2: %02X\n", val); - rev |= val << BITS_PER_BYTE; - - pmic->dev = &pdev->dev; - pm8921_drvdata.pm_chip_data = pmic; - platform_set_drvdata(pdev, &pm8921_drvdata); - - rc = pm8921_add_subdevices(pdata, pmic, rev); - if (rc) { - pr_err("Cannot add subdevices rc=%d\n", rc); - goto err; - } - - /* gpio might not work if no irq device is found */ - WARN_ON(pmic->irq_chip == NULL); - - return 0; - -err: - mfd_remove_devices(pmic->dev); - platform_set_drvdata(pdev, NULL); -err_read_rev: - kfree(pmic); - return rc; -} - -static int __devexit pm8921_remove(struct platform_device *pdev) -{ - struct pm8xxx_drvdata *drvdata; - struct pm8921 *pmic = NULL; - - drvdata = platform_get_drvdata(pdev); - if (drvdata) - pmic = drvdata->pm_chip_data; - if (pmic) - mfd_remove_devices(pmic->dev); - if (pmic->irq_chip) { - pm8xxx_irq_exit(pmic->irq_chip); - pmic->irq_chip = NULL; - } - platform_set_drvdata(pdev, NULL); - kfree(pmic); - - return 0; -} - -static struct platform_driver pm8921_driver = { - .probe = pm8921_probe, - .remove = __devexit_p(pm8921_remove), - .driver = { - .name = "pm8921-core", - .owner = THIS_MODULE, - }, -}; - -static int __init pm8921_init(void) -{ - return platform_driver_register(&pm8921_driver); -} -subsys_initcall(pm8921_init); - -static void __exit pm8921_exit(void) -{ - platform_driver_unregister(&pm8921_driver); -} -module_exit(pm8921_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PMIC 8921 core driver"); -MODULE_VERSION("1.0"); -MODULE_ALIAS("platform:pm8921-core"); diff --git a/ANDROID_3.4.5/drivers/mfd/pm8xxx-irq.c b/ANDROID_3.4.5/drivers/mfd/pm8xxx-irq.c deleted file mode 100644 index d452dd01..00000000 --- a/ANDROID_3.4.5/drivers/mfd/pm8xxx-irq.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * 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. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include <linux/err.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/mfd/pm8xxx/core.h> -#include <linux/mfd/pm8xxx/irq.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -/* PMIC8xxx IRQ */ - -#define SSBI_REG_ADDR_IRQ_BASE 0x1BB - -#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0) -#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1) -#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2) -#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3) -#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4) -#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5) -#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6) -#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7) -#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8) - -#define PM_IRQF_LVL_SEL 0x01 /* level select */ -#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */ -#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */ -#define PM_IRQF_CLR 0x08 /* clear interrupt */ -#define PM_IRQF_BITS_MASK 0x70 -#define PM_IRQF_BITS_SHIFT 4 -#define PM_IRQF_WRITE 0x80 - -#define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \ - PM_IRQF_MASK_RE) - -struct pm_irq_chip { - struct device *dev; - spinlock_t pm_irq_lock; - unsigned int devirq; - unsigned int irq_base; - unsigned int num_irqs; - unsigned int num_blocks; - unsigned int num_masters; - u8 config[0]; -}; - -static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp) -{ - return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp); -} - -static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp) -{ - return pm8xxx_readb(chip->dev, - SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp); -} - -static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip) -{ - int rc; - - spin_lock(&chip->pm_irq_lock); - rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); - if (rc) { - pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); - goto bail; - } - - rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); - if (rc) - pr_err("Failed Reading Status rc=%d\n", rc); -bail: - spin_unlock(&chip->pm_irq_lock); - return rc; -} - -static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp) -{ - int rc; - - spin_lock(&chip->pm_irq_lock); - rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); - if (rc) { - pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); - goto bail; - } - - cp |= PM_IRQF_WRITE; - rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp); - if (rc) - pr_err("Failed Configuring IRQ rc=%d\n", rc); -bail: - spin_unlock(&chip->pm_irq_lock); - return rc; -} - -static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) -{ - int pmirq, irq, i, ret = 0; - u8 bits; - - ret = pm8xxx_read_block_irq(chip, block, &bits); - if (ret) { - pr_err("Failed reading %d block ret=%d", block, ret); - return ret; - } - if (!bits) { - pr_err("block bit set in master but no irqs: %d", block); - return 0; - } - - /* Check IRQ bits */ - for (i = 0; i < 8; i++) { - if (bits & (1 << i)) { - pmirq = block * 8 + i; - irq = pmirq + chip->irq_base; - generic_handle_irq(irq); - } - } - return 0; -} - -static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master) -{ - u8 blockbits; - int block_number, i, ret = 0; - - ret = pm8xxx_read_master_irq(chip, master, &blockbits); - if (ret) { - pr_err("Failed to read master %d ret=%d\n", master, ret); - return ret; - } - if (!blockbits) { - pr_err("master bit set in root but no blocks: %d", master); - return 0; - } - - for (i = 0; i < 8; i++) - if (blockbits & (1 << i)) { - block_number = master * 8 + i; /* block # */ - ret |= pm8xxx_irq_block_handler(chip, block_number); - } - return ret; -} - -static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - struct pm_irq_chip *chip = irq_desc_get_handler_data(desc); - struct irq_chip *irq_chip = irq_desc_get_chip(desc); - u8 root; - int i, ret, masters = 0; - - ret = pm8xxx_read_root_irq(chip, &root); - if (ret) { - pr_err("Can't read root status ret=%d\n", ret); - return; - } - - /* on pm8xxx series masters start from bit 1 of the root */ - masters = root >> 1; - - /* Read allowed masters for blocks. */ - for (i = 0; i < chip->num_masters; i++) - if (masters & (1 << i)) - pm8xxx_irq_master_handler(chip, i); - - irq_chip->irq_ack(&desc->irq_data); -} - -static void pm8xxx_irq_mask_ack(struct irq_data *d) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = d->irq - chip->irq_base; - int master, irq_bit; - u8 block, config; - - block = pmirq / 8; - master = block / 8; - irq_bit = pmirq % 8; - - config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; - pm8xxx_config_irq(chip, block, config); -} - -static void pm8xxx_irq_unmask(struct irq_data *d) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = d->irq - chip->irq_base; - int master, irq_bit; - u8 block, config; - - block = pmirq / 8; - master = block / 8; - irq_bit = pmirq % 8; - - config = chip->config[pmirq]; - pm8xxx_config_irq(chip, block, config); -} - -static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = d->irq - chip->irq_base; - int master, irq_bit; - u8 block, config; - - block = pmirq / 8; - master = block / 8; - irq_bit = pmirq % 8; - - chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT) - | PM_IRQF_MASK_ALL; - if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { - if (flow_type & IRQF_TRIGGER_RISING) - chip->config[pmirq] &= ~PM_IRQF_MASK_RE; - if (flow_type & IRQF_TRIGGER_FALLING) - chip->config[pmirq] &= ~PM_IRQF_MASK_FE; - } else { - chip->config[pmirq] |= PM_IRQF_LVL_SEL; - - if (flow_type & IRQF_TRIGGER_HIGH) - chip->config[pmirq] &= ~PM_IRQF_MASK_RE; - else - chip->config[pmirq] &= ~PM_IRQF_MASK_FE; - } - - config = chip->config[pmirq] | PM_IRQF_CLR; - return pm8xxx_config_irq(chip, block, config); -} - -static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on) -{ - return 0; -} - -static struct irq_chip pm8xxx_irq_chip = { - .name = "pm8xxx", - .irq_mask_ack = pm8xxx_irq_mask_ack, - .irq_unmask = pm8xxx_irq_unmask, - .irq_set_type = pm8xxx_irq_set_type, - .irq_set_wake = pm8xxx_irq_set_wake, - .flags = IRQCHIP_MASK_ON_SUSPEND, -}; - -/** - * pm8xxx_get_irq_stat - get the status of the irq line - * @chip: pointer to identify a pmic irq controller - * @irq: the irq number - * - * The pm8xxx gpio and mpp rely on the interrupt block to read - * the values on their pins. This function is to facilitate reading - * the status of a gpio or an mpp line. The caller has to convert the - * gpio number to irq number. - * - * RETURNS: - * an int indicating the value read on that line - */ -int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) -{ - int pmirq, rc; - u8 block, bits, bit; - unsigned long flags; - - if (chip == NULL || irq < chip->irq_base || - irq >= chip->irq_base + chip->num_irqs) - return -EINVAL; - - pmirq = irq - chip->irq_base; - - block = pmirq / 8; - bit = pmirq % 8; - - spin_lock_irqsave(&chip->pm_irq_lock, flags); - - rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block); - if (rc) { - pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", - irq, pmirq, block, rc); - goto bail_out; - } - - rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); - if (rc) { - pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", - irq, pmirq, block, rc); - goto bail_out; - } - - rc = (bits & (1 << bit)) ? 1 : 0; - -bail_out: - spin_unlock_irqrestore(&chip->pm_irq_lock, flags); - - return rc; -} -EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat); - -struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev, - const struct pm8xxx_irq_platform_data *pdata) -{ - struct pm_irq_chip *chip; - int devirq, rc; - unsigned int pmirq; - - if (!pdata) { - pr_err("No platform data\n"); - return ERR_PTR(-EINVAL); - } - - devirq = pdata->devirq; - if (devirq < 0) { - pr_err("missing devirq\n"); - rc = devirq; - return ERR_PTR(-EINVAL); - } - - chip = kzalloc(sizeof(struct pm_irq_chip) - + sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL); - if (!chip) { - pr_err("Cannot alloc pm_irq_chip struct\n"); - return ERR_PTR(-EINVAL); - } - - chip->dev = dev; - chip->devirq = devirq; - chip->irq_base = pdata->irq_base; - chip->num_irqs = pdata->irq_cdata.nirqs; - chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); - chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); - spin_lock_init(&chip->pm_irq_lock); - - for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) { - irq_set_chip_and_handler(chip->irq_base + pmirq, - &pm8xxx_irq_chip, - handle_level_irq); - irq_set_chip_data(chip->irq_base + pmirq, chip); -#ifdef CONFIG_ARM - set_irq_flags(chip->irq_base + pmirq, IRQF_VALID); -#else - irq_set_noprobe(chip->irq_base + pmirq); -#endif - } - - irq_set_irq_type(devirq, pdata->irq_trigger_flag); - irq_set_handler_data(devirq, chip); - irq_set_chained_handler(devirq, pm8xxx_irq_handler); - set_irq_wake(devirq, 1); - - return chip; -} - -int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip) -{ - irq_set_chained_handler(chip->devirq, NULL); - kfree(chip); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/rc5t583-irq.c b/ANDROID_3.4.5/drivers/mfd/rc5t583-irq.c deleted file mode 100644 index fa6f80fa..00000000 --- a/ANDROID_3.4.5/drivers/mfd/rc5t583-irq.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Interrupt driver for RICOH583 power management chip. - * - * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. - * Author: Laxman dewangan <ldewangan@nvidia.com> - * - * based on code - * Copyright (C) 2011 RICOH COMPANY,LTD - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. - * - */ -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/mfd/rc5t583.h> - -enum int_type { - SYS_INT = 0x1, - DCDC_INT = 0x2, - RTC_INT = 0x4, - ADC_INT = 0x8, - GPIO_INT = 0x10, -}; - -static int gpedge_add[] = { - RC5T583_GPIO_GPEDGE2, - RC5T583_GPIO_GPEDGE2 -}; - -static int irq_en_add[] = { - RC5T583_INT_EN_SYS1, - RC5T583_INT_EN_SYS2, - RC5T583_INT_EN_DCDC, - RC5T583_INT_EN_RTC, - RC5T583_INT_EN_ADC1, - RC5T583_INT_EN_ADC2, - RC5T583_INT_EN_ADC3, - RC5T583_GPIO_EN_INT -}; - -static int irq_mon_add[] = { - RC5T583_INT_MON_SYS1, - RC5T583_INT_MON_SYS2, - RC5T583_INT_MON_DCDC, - RC5T583_INT_MON_RTC, - RC5T583_INT_IR_ADCL, - RC5T583_INT_IR_ADCH, - RC5T583_INT_IR_ADCEND, - RC5T583_INT_IR_GPIOF, - RC5T583_INT_IR_GPIOR -}; - -static int irq_clr_add[] = { - RC5T583_INT_IR_SYS1, - RC5T583_INT_IR_SYS2, - RC5T583_INT_IR_DCDC, - RC5T583_INT_IR_RTC, - RC5T583_INT_IR_ADCL, - RC5T583_INT_IR_ADCH, - RC5T583_INT_IR_ADCEND, - RC5T583_INT_IR_GPIOF, - RC5T583_INT_IR_GPIOR -}; - -static int main_int_type[] = { - SYS_INT, - SYS_INT, - DCDC_INT, - RTC_INT, - ADC_INT, - ADC_INT, - ADC_INT, - GPIO_INT, - GPIO_INT, -}; - -struct rc5t583_irq_data { - u8 int_type; - u8 master_bit; - u8 int_en_bit; - u8 mask_reg_index; - int grp_index; -}; - -#define RC5T583_IRQ(_int_type, _master_bit, _grp_index, \ - _int_bit, _mask_ind) \ - { \ - .int_type = _int_type, \ - .master_bit = _master_bit, \ - .grp_index = _grp_index, \ - .int_en_bit = _int_bit, \ - .mask_reg_index = _mask_ind, \ - } - -static const struct rc5t583_irq_data rc5t583_irqs[RC5T583_MAX_IRQS] = { - [RC5T583_IRQ_ONKEY] = RC5T583_IRQ(SYS_INT, 0, 0, 0, 0), - [RC5T583_IRQ_ACOK] = RC5T583_IRQ(SYS_INT, 0, 1, 1, 0), - [RC5T583_IRQ_LIDOPEN] = RC5T583_IRQ(SYS_INT, 0, 2, 2, 0), - [RC5T583_IRQ_PREOT] = RC5T583_IRQ(SYS_INT, 0, 3, 3, 0), - [RC5T583_IRQ_CLKSTP] = RC5T583_IRQ(SYS_INT, 0, 4, 4, 0), - [RC5T583_IRQ_ONKEY_OFF] = RC5T583_IRQ(SYS_INT, 0, 5, 5, 0), - [RC5T583_IRQ_WD] = RC5T583_IRQ(SYS_INT, 0, 7, 7, 0), - [RC5T583_IRQ_EN_PWRREQ1] = RC5T583_IRQ(SYS_INT, 0, 8, 0, 1), - [RC5T583_IRQ_EN_PWRREQ2] = RC5T583_IRQ(SYS_INT, 0, 9, 1, 1), - [RC5T583_IRQ_PRE_VINDET] = RC5T583_IRQ(SYS_INT, 0, 10, 2, 1), - - [RC5T583_IRQ_DC0LIM] = RC5T583_IRQ(DCDC_INT, 1, 0, 0, 2), - [RC5T583_IRQ_DC1LIM] = RC5T583_IRQ(DCDC_INT, 1, 1, 1, 2), - [RC5T583_IRQ_DC2LIM] = RC5T583_IRQ(DCDC_INT, 1, 2, 2, 2), - [RC5T583_IRQ_DC3LIM] = RC5T583_IRQ(DCDC_INT, 1, 3, 3, 2), - - [RC5T583_IRQ_CTC] = RC5T583_IRQ(RTC_INT, 2, 0, 0, 3), - [RC5T583_IRQ_YALE] = RC5T583_IRQ(RTC_INT, 2, 5, 5, 3), - [RC5T583_IRQ_DALE] = RC5T583_IRQ(RTC_INT, 2, 6, 6, 3), - [RC5T583_IRQ_WALE] = RC5T583_IRQ(RTC_INT, 2, 7, 7, 3), - - [RC5T583_IRQ_AIN1L] = RC5T583_IRQ(ADC_INT, 3, 0, 0, 4), - [RC5T583_IRQ_AIN2L] = RC5T583_IRQ(ADC_INT, 3, 1, 1, 4), - [RC5T583_IRQ_AIN3L] = RC5T583_IRQ(ADC_INT, 3, 2, 2, 4), - [RC5T583_IRQ_VBATL] = RC5T583_IRQ(ADC_INT, 3, 3, 3, 4), - [RC5T583_IRQ_VIN3L] = RC5T583_IRQ(ADC_INT, 3, 4, 4, 4), - [RC5T583_IRQ_VIN8L] = RC5T583_IRQ(ADC_INT, 3, 5, 5, 4), - [RC5T583_IRQ_AIN1H] = RC5T583_IRQ(ADC_INT, 3, 6, 0, 5), - [RC5T583_IRQ_AIN2H] = RC5T583_IRQ(ADC_INT, 3, 7, 1, 5), - [RC5T583_IRQ_AIN3H] = RC5T583_IRQ(ADC_INT, 3, 8, 2, 5), - [RC5T583_IRQ_VBATH] = RC5T583_IRQ(ADC_INT, 3, 9, 3, 5), - [RC5T583_IRQ_VIN3H] = RC5T583_IRQ(ADC_INT, 3, 10, 4, 5), - [RC5T583_IRQ_VIN8H] = RC5T583_IRQ(ADC_INT, 3, 11, 5, 5), - [RC5T583_IRQ_ADCEND] = RC5T583_IRQ(ADC_INT, 3, 12, 0, 6), - - [RC5T583_IRQ_GPIO0] = RC5T583_IRQ(GPIO_INT, 4, 0, 0, 7), - [RC5T583_IRQ_GPIO1] = RC5T583_IRQ(GPIO_INT, 4, 1, 1, 7), - [RC5T583_IRQ_GPIO2] = RC5T583_IRQ(GPIO_INT, 4, 2, 2, 7), - [RC5T583_IRQ_GPIO3] = RC5T583_IRQ(GPIO_INT, 4, 3, 3, 7), - [RC5T583_IRQ_GPIO4] = RC5T583_IRQ(GPIO_INT, 4, 4, 4, 7), - [RC5T583_IRQ_GPIO5] = RC5T583_IRQ(GPIO_INT, 4, 5, 5, 7), - [RC5T583_IRQ_GPIO6] = RC5T583_IRQ(GPIO_INT, 4, 6, 6, 7), - [RC5T583_IRQ_GPIO7] = RC5T583_IRQ(GPIO_INT, 4, 7, 7, 7), -}; - -static void rc5t583_irq_lock(struct irq_data *irq_data) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - mutex_lock(&rc5t583->irq_lock); -} - -static void rc5t583_irq_unmask(struct irq_data *irq_data) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - rc5t583->irq_base; - const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq]; - - rc5t583->group_irq_en[data->grp_index] |= 1 << data->grp_index; - rc5t583->intc_inten_reg |= 1 << data->master_bit; - rc5t583->irq_en_reg[data->mask_reg_index] |= 1 << data->int_en_bit; -} - -static void rc5t583_irq_mask(struct irq_data *irq_data) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - rc5t583->irq_base; - const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq]; - - rc5t583->group_irq_en[data->grp_index] &= ~(1 << data->grp_index); - if (!rc5t583->group_irq_en[data->grp_index]) - rc5t583->intc_inten_reg &= ~(1 << data->master_bit); - - rc5t583->irq_en_reg[data->mask_reg_index] &= ~(1 << data->int_en_bit); -} - -static int rc5t583_irq_set_type(struct irq_data *irq_data, unsigned int type) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - rc5t583->irq_base; - const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq]; - int val = 0; - int gpedge_index; - int gpedge_bit_pos; - - /* Supporting only trigger level inetrrupt */ - if ((data->int_type & GPIO_INT) && (type & IRQ_TYPE_EDGE_BOTH)) { - gpedge_index = data->int_en_bit / 4; - gpedge_bit_pos = data->int_en_bit % 4; - - if (type & IRQ_TYPE_EDGE_FALLING) - val |= 0x2; - - if (type & IRQ_TYPE_EDGE_RISING) - val |= 0x1; - - rc5t583->gpedge_reg[gpedge_index] &= ~(3 << gpedge_bit_pos); - rc5t583->gpedge_reg[gpedge_index] |= (val << gpedge_bit_pos); - rc5t583_irq_unmask(irq_data); - return 0; - } - return -EINVAL; -} - -static void rc5t583_irq_sync_unlock(struct irq_data *irq_data) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - int i; - int ret; - - for (i = 0; i < ARRAY_SIZE(rc5t583->gpedge_reg); i++) { - ret = rc5t583_write(rc5t583->dev, gpedge_add[i], - rc5t583->gpedge_reg[i]); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - gpedge_add[i], ret); - } - - for (i = 0; i < ARRAY_SIZE(rc5t583->irq_en_reg); i++) { - ret = rc5t583_write(rc5t583->dev, irq_en_add[i], - rc5t583->irq_en_reg[i]); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - irq_en_add[i], ret); - } - - ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN, - rc5t583->intc_inten_reg); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - RC5T583_INTC_INTEN, ret); - - mutex_unlock(&rc5t583->irq_lock); -} -#ifdef CONFIG_PM_SLEEP -static int rc5t583_irq_set_wake(struct irq_data *irq_data, unsigned int on) -{ - struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data); - return irq_set_irq_wake(rc5t583->chip_irq, on); -} -#else -#define rc5t583_irq_set_wake NULL -#endif - -static irqreturn_t rc5t583_irq(int irq, void *data) -{ - struct rc5t583 *rc5t583 = data; - uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS]; - uint8_t master_int; - int i; - int ret; - unsigned int rtc_int_sts = 0; - - /* Clear the status */ - for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) - int_sts[i] = 0; - - ret = rc5t583_read(rc5t583->dev, RC5T583_INTC_INTMON, &master_int); - if (ret < 0) { - dev_err(rc5t583->dev, - "Error in reading reg 0x%02x error: %d\n", - RC5T583_INTC_INTMON, ret); - return IRQ_HANDLED; - } - - for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; ++i) { - if (!(master_int & main_int_type[i])) - continue; - - ret = rc5t583_read(rc5t583->dev, irq_mon_add[i], &int_sts[i]); - if (ret < 0) { - dev_warn(rc5t583->dev, - "Error in reading reg 0x%02x error: %d\n", - irq_mon_add[i], ret); - int_sts[i] = 0; - continue; - } - - if (main_int_type[i] & RTC_INT) { - rtc_int_sts = 0; - if (int_sts[i] & 0x1) - rtc_int_sts |= BIT(6); - if (int_sts[i] & 0x2) - rtc_int_sts |= BIT(7); - if (int_sts[i] & 0x4) - rtc_int_sts |= BIT(0); - if (int_sts[i] & 0x8) - rtc_int_sts |= BIT(5); - } - - ret = rc5t583_write(rc5t583->dev, irq_clr_add[i], - ~int_sts[i]); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in reading reg 0x%02x error: %d\n", - irq_clr_add[i], ret); - - if (main_int_type[i] & RTC_INT) - int_sts[i] = rtc_int_sts; - } - - /* Merge gpio interrupts for rising and falling case*/ - int_sts[7] |= int_sts[8]; - - /* Call interrupt handler if enabled */ - for (i = 0; i < RC5T583_MAX_IRQS; ++i) { - const struct rc5t583_irq_data *data = &rc5t583_irqs[i]; - if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) && - (rc5t583->group_irq_en[data->master_bit] & - (1 << data->grp_index))) - handle_nested_irq(rc5t583->irq_base + i); - } - - return IRQ_HANDLED; -} - -static struct irq_chip rc5t583_irq_chip = { - .name = "rc5t583-irq", - .irq_mask = rc5t583_irq_mask, - .irq_unmask = rc5t583_irq_unmask, - .irq_bus_lock = rc5t583_irq_lock, - .irq_bus_sync_unlock = rc5t583_irq_sync_unlock, - .irq_set_type = rc5t583_irq_set_type, - .irq_set_wake = rc5t583_irq_set_wake, -}; - -int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base) -{ - int i, ret; - - if (!irq_base) { - dev_warn(rc5t583->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } - - mutex_init(&rc5t583->irq_lock); - - /* Initailize all int register to 0 */ - for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) { - ret = rc5t583_write(rc5t583->dev, irq_en_add[i], - rc5t583->irq_en_reg[i]); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - irq_en_add[i], ret); - } - - for (i = 0; i < RC5T583_MAX_GPEDGE_REG; i++) { - ret = rc5t583_write(rc5t583->dev, gpedge_add[i], - rc5t583->gpedge_reg[i]); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - gpedge_add[i], ret); - } - - ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN, 0x0); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - RC5T583_INTC_INTEN, ret); - - /* Clear all interrupts in case they woke up active. */ - for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) { - ret = rc5t583_write(rc5t583->dev, irq_clr_add[i], 0); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - irq_clr_add[i], ret); - } - - rc5t583->irq_base = irq_base; - rc5t583->chip_irq = irq; - - for (i = 0; i < RC5T583_MAX_IRQS; i++) { - int __irq = i + rc5t583->irq_base; - irq_set_chip_data(__irq, rc5t583); - irq_set_chip_and_handler(__irq, &rc5t583_irq_chip, - handle_simple_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#endif - } - - ret = request_threaded_irq(irq, NULL, rc5t583_irq, IRQF_ONESHOT, - "rc5t583", rc5t583); - if (ret < 0) - dev_err(rc5t583->dev, - "Error in registering interrupt error: %d\n", ret); - return ret; -} - -int rc5t583_irq_exit(struct rc5t583 *rc5t583) -{ - if (rc5t583->chip_irq) - free_irq(rc5t583->chip_irq, rc5t583); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/rc5t583.c b/ANDROID_3.4.5/drivers/mfd/rc5t583.c deleted file mode 100644 index 44afae0a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/rc5t583.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Core driver access RC5T583 power management chip. - * - * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. - * Author: Laxman dewangan <ldewangan@nvidia.com> - * - * Based on code - * Copyright (C) 2011 RICOH COMPANY,LTD - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. - * - */ -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/rc5t583.h> -#include <linux/regmap.h> - -#define RICOH_ONOFFSEL_REG 0x10 -#define RICOH_SWCTL_REG 0x5E - -struct deepsleep_control_data { - u8 reg_add; - u8 ds_pos_bit; -}; - -#define DEEPSLEEP_INIT(_id, _reg, _pos) \ - { \ - .reg_add = RC5T583_##_reg, \ - .ds_pos_bit = _pos, \ - } - -static struct deepsleep_control_data deepsleep_data[] = { - DEEPSLEEP_INIT(DC0, SLPSEQ1, 0), - DEEPSLEEP_INIT(DC1, SLPSEQ1, 4), - DEEPSLEEP_INIT(DC2, SLPSEQ2, 0), - DEEPSLEEP_INIT(DC3, SLPSEQ2, 4), - DEEPSLEEP_INIT(LDO0, SLPSEQ3, 0), - DEEPSLEEP_INIT(LDO1, SLPSEQ3, 4), - DEEPSLEEP_INIT(LDO2, SLPSEQ4, 0), - DEEPSLEEP_INIT(LDO3, SLPSEQ4, 4), - DEEPSLEEP_INIT(LDO4, SLPSEQ5, 0), - DEEPSLEEP_INIT(LDO5, SLPSEQ5, 4), - DEEPSLEEP_INIT(LDO6, SLPSEQ6, 0), - DEEPSLEEP_INIT(LDO7, SLPSEQ6, 4), - DEEPSLEEP_INIT(LDO8, SLPSEQ7, 0), - DEEPSLEEP_INIT(LDO9, SLPSEQ7, 4), - DEEPSLEEP_INIT(PSO0, SLPSEQ8, 0), - DEEPSLEEP_INIT(PSO1, SLPSEQ8, 4), - DEEPSLEEP_INIT(PSO2, SLPSEQ9, 0), - DEEPSLEEP_INIT(PSO3, SLPSEQ9, 4), - DEEPSLEEP_INIT(PSO4, SLPSEQ10, 0), - DEEPSLEEP_INIT(PSO5, SLPSEQ10, 4), - DEEPSLEEP_INIT(PSO6, SLPSEQ11, 0), - DEEPSLEEP_INIT(PSO7, SLPSEQ11, 4), -}; - -#define EXT_PWR_REQ \ - (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL) - -static struct mfd_cell rc5t583_subdevs[] = { - {.name = "rc5t583-regulator",}, - {.name = "rc5t583-rtc", }, - {.name = "rc5t583-key", } -}; - -static int __rc5t583_set_ext_pwrreq1_control(struct device *dev, - int id, int ext_pwr, int slots) -{ - int ret; - uint8_t sleepseq_val; - unsigned int en_bit; - unsigned int slot_bit; - - if (id == RC5T583_DS_DC0) { - dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id); - return -EINVAL; - } - - en_bit = deepsleep_data[id].ds_pos_bit; - slot_bit = en_bit + 1; - ret = rc5t583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val); - if (ret < 0) { - dev_err(dev, "Error in reading reg 0x%x\n", - deepsleep_data[id].reg_add); - return ret; - } - - sleepseq_val &= ~(0xF << en_bit); - sleepseq_val |= BIT(en_bit); - sleepseq_val |= ((slots & 0x7) << slot_bit); - ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(1)); - if (ret < 0) { - dev_err(dev, "Error in updating the 0x%02x register\n", - RICOH_ONOFFSEL_REG); - return ret; - } - - ret = rc5t583_write(dev, deepsleep_data[id].reg_add, sleepseq_val); - if (ret < 0) { - dev_err(dev, "Error in writing reg 0x%x\n", - deepsleep_data[id].reg_add); - return ret; - } - - if (id == RC5T583_DS_LDO4) { - ret = rc5t583_write(dev, RICOH_SWCTL_REG, 0x1); - if (ret < 0) - dev_err(dev, "Error in writing reg 0x%x\n", - RICOH_SWCTL_REG); - } - return ret; -} - -static int __rc5t583_set_ext_pwrreq2_control(struct device *dev, - int id, int ext_pwr) -{ - int ret; - - if (id != RC5T583_DS_DC0) { - dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id); - return -EINVAL; - } - - ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(2)); - if (ret < 0) - dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n"); - return ret; -} - -int rc5t583_ext_power_req_config(struct device *dev, int ds_id, - int ext_pwr_req, int deepsleep_slot_nr) -{ - if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ) - return -EINVAL; - - if (ext_pwr_req & RC5T583_EXT_PWRREQ1_CONTROL) - return __rc5t583_set_ext_pwrreq1_control(dev, ds_id, - ext_pwr_req, deepsleep_slot_nr); - - if (ext_pwr_req & RC5T583_EXT_PWRREQ2_CONTROL) - return __rc5t583_set_ext_pwrreq2_control(dev, - ds_id, ext_pwr_req); - return 0; -} -EXPORT_SYMBOL(rc5t583_ext_power_req_config); - -static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, - struct rc5t583_platform_data *pdata) -{ - int ret; - int i; - uint8_t on_off_val = 0; - - /* Clear ONOFFSEL register */ - if (pdata->enable_shutdown) - on_off_val = 0x1; - - ret = rc5t583_write(rc5t583->dev, RICOH_ONOFFSEL_REG, on_off_val); - if (ret < 0) - dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n", - RICOH_ONOFFSEL_REG, ret); - - ret = rc5t583_write(rc5t583->dev, RICOH_SWCTL_REG, 0x0); - if (ret < 0) - dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n", - RICOH_SWCTL_REG, ret); - - /* Clear sleep sequence register */ - for (i = RC5T583_SLPSEQ1; i <= RC5T583_SLPSEQ11; ++i) { - ret = rc5t583_write(rc5t583->dev, i, 0x0); - if (ret < 0) - dev_warn(rc5t583->dev, - "Error in writing reg 0x%02x error: %d\n", - i, ret); - } - return 0; -} - -static bool volatile_reg(struct device *dev, unsigned int reg) -{ - /* Enable caching in interrupt registers */ - switch (reg) { - case RC5T583_INT_EN_SYS1: - case RC5T583_INT_EN_SYS2: - case RC5T583_INT_EN_DCDC: - case RC5T583_INT_EN_RTC: - case RC5T583_INT_EN_ADC1: - case RC5T583_INT_EN_ADC2: - case RC5T583_INT_EN_ADC3: - case RC5T583_GPIO_GPEDGE1: - case RC5T583_GPIO_GPEDGE2: - case RC5T583_GPIO_EN_INT: - return false; - - case RC5T583_GPIO_MON_IOIN: - /* This is gpio input register */ - return true; - - default: - /* Enable caching in gpio registers */ - if ((reg >= RC5T583_GPIO_IOSEL) && - (reg <= RC5T583_GPIO_GPOFUNC)) - return false; - - /* Enable caching in sleep seq registers */ - if ((reg >= RC5T583_SLPSEQ1) && (reg <= RC5T583_SLPSEQ11)) - return false; - - /* Enable caching of regulator registers */ - if ((reg >= RC5T583_REG_DC0CTL) && (reg <= RC5T583_REG_SR3CTL)) - return false; - if ((reg >= RC5T583_REG_LDOEN1) && - (reg <= RC5T583_REG_LDO9DAC_DS)) - return false; - - break; - } - - return true; -} - -static const struct regmap_config rc5t583_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .volatile_reg = volatile_reg, - .max_register = RC5T583_MAX_REGS, - .num_reg_defaults_raw = RC5T583_MAX_REGS, - .cache_type = REGCACHE_RBTREE, -}; - -static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct rc5t583 *rc5t583; - struct rc5t583_platform_data *pdata = i2c->dev.platform_data; - int ret; - bool irq_init_success = false; - - if (!pdata) { - dev_err(&i2c->dev, "Err: Platform data not found\n"); - return -EINVAL; - } - - rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL); - if (!rc5t583) { - dev_err(&i2c->dev, "Memory allocation failed\n"); - return -ENOMEM; - } - - rc5t583->dev = &i2c->dev; - i2c_set_clientdata(i2c, rc5t583); - - rc5t583->regmap = regmap_init_i2c(i2c, &rc5t583_regmap_config); - if (IS_ERR(rc5t583->regmap)) { - ret = PTR_ERR(rc5t583->regmap); - dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); - return ret; - } - - ret = rc5t583_clear_ext_power_req(rc5t583, pdata); - if (ret < 0) - goto err_irq_init; - - if (i2c->irq) { - ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base); - /* Still continue with waring if irq init fails */ - if (ret) - dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret); - else - irq_init_success = true; - } - - ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, - ARRAY_SIZE(rc5t583_subdevs), NULL, 0); - if (ret) { - dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); - goto err_add_devs; - } - - return 0; - -err_add_devs: - if (irq_init_success) - rc5t583_irq_exit(rc5t583); -err_irq_init: - regmap_exit(rc5t583->regmap); - return ret; -} - -static int __devexit rc5t583_i2c_remove(struct i2c_client *i2c) -{ - struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c); - - mfd_remove_devices(rc5t583->dev); - rc5t583_irq_exit(rc5t583); - regmap_exit(rc5t583->regmap); - return 0; -} - -static const struct i2c_device_id rc5t583_i2c_id[] = { - {.name = "rc5t583", .driver_data = 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, rc5t583_i2c_id); - -static struct i2c_driver rc5t583_i2c_driver = { - .driver = { - .name = "rc5t583", - .owner = THIS_MODULE, - }, - .probe = rc5t583_i2c_probe, - .remove = __devexit_p(rc5t583_i2c_remove), - .id_table = rc5t583_i2c_id, -}; - -static int __init rc5t583_i2c_init(void) -{ - return i2c_add_driver(&rc5t583_i2c_driver); -} -subsys_initcall(rc5t583_i2c_init); - -static void __exit rc5t583_i2c_exit(void) -{ - i2c_del_driver(&rc5t583_i2c_driver); -} - -module_exit(rc5t583_i2c_exit); - -MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); -MODULE_DESCRIPTION("RICOH RC5T583 power management system device driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/rdc321x-southbridge.c b/ANDROID_3.4.5/drivers/mfd/rdc321x-southbridge.c deleted file mode 100644 index 809bd4a6..00000000 --- a/ANDROID_3.4.5/drivers/mfd/rdc321x-southbridge.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * RDC321x MFD southbrige driver - * - * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org> - * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/pci.h> -#include <linux/mfd/core.h> -#include <linux/mfd/rdc321x.h> - -static struct rdc321x_wdt_pdata rdc321x_wdt_pdata; - -static struct resource rdc321x_wdt_resource[] = { - { - .name = "wdt-reg", - .start = RDC321X_WDT_CTRL, - .end = RDC321X_WDT_CTRL + 0x3, - .flags = IORESOURCE_IO, - } -}; - -static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { - .max_gpios = RDC321X_MAX_GPIO, -}; - -static struct resource rdc321x_gpio_resources[] = { - { - .name = "gpio-reg1", - .start = RDC321X_GPIO_CTRL_REG1, - .end = RDC321X_GPIO_CTRL_REG1 + 0x7, - .flags = IORESOURCE_IO, - }, { - .name = "gpio-reg2", - .start = RDC321X_GPIO_CTRL_REG2, - .end = RDC321X_GPIO_CTRL_REG2 + 0x7, - .flags = IORESOURCE_IO, - } -}; - -static struct mfd_cell rdc321x_sb_cells[] = { - { - .name = "rdc321x-wdt", - .resources = rdc321x_wdt_resource, - .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), - .platform_data = &rdc321x_wdt_pdata, - .pdata_size = sizeof(rdc321x_wdt_pdata), - }, { - .name = "rdc321x-gpio", - .resources = rdc321x_gpio_resources, - .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), - .platform_data = &rdc321x_gpio_pdata, - .pdata_size = sizeof(rdc321x_gpio_pdata), - }, -}; - -static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int err; - - err = pci_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "failed to enable device\n"); - return err; - } - - rdc321x_gpio_pdata.sb_pdev = pdev; - rdc321x_wdt_pdata.sb_pdev = pdev; - - return mfd_add_devices(&pdev->dev, -1, - rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); -} - -static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) -{ - mfd_remove_devices(&pdev->dev); -} - -static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, - {} -}; -MODULE_DEVICE_TABLE(pci, rdc321x_sb_table); - -static struct pci_driver rdc321x_sb_driver = { - .name = "RDC321x Southbridge", - .id_table = rdc321x_sb_table, - .probe = rdc321x_sb_probe, - .remove = __devexit_p(rdc321x_sb_remove), -}; - -static int __init rdc321x_sb_init(void) -{ - return pci_register_driver(&rdc321x_sb_driver); -} - -static void __exit rdc321x_sb_exit(void) -{ - pci_unregister_driver(&rdc321x_sb_driver); -} - -module_init(rdc321x_sb_init); -module_exit(rdc321x_sb_exit); - -MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver"); diff --git a/ANDROID_3.4.5/drivers/mfd/s5m-core.c b/ANDROID_3.4.5/drivers/mfd/s5m-core.c deleted file mode 100644 index 48949d99..00000000 --- a/ANDROID_3.4.5/drivers/mfd/s5m-core.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * s5m87xx.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/pm_runtime.h> -#include <linux/mutex.h> -#include <linux/mfd/core.h> -#include <linux/mfd/s5m87xx/s5m-core.h> -#include <linux/mfd/s5m87xx/s5m-pmic.h> -#include <linux/mfd/s5m87xx/s5m-rtc.h> -#include <linux/regmap.h> - -static struct mfd_cell s5m8751_devs[] = { - { - .name = "s5m8751-pmic", - }, { - .name = "s5m-charger", - }, { - .name = "s5m8751-codec", - }, -}; - -static struct mfd_cell s5m8763_devs[] = { - { - .name = "s5m8763-pmic", - }, { - .name = "s5m-rtc", - }, { - .name = "s5m-charger", - }, -}; - -static struct mfd_cell s5m8767_devs[] = { - { - .name = "s5m8767-pmic", - }, { - .name = "s5m-rtc", - }, -}; - -int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest) -{ - return regmap_read(s5m87xx->regmap, reg, dest); -} -EXPORT_SYMBOL_GPL(s5m_reg_read); - -int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) -{ - return regmap_bulk_read(s5m87xx->regmap, reg, buf, count); -} -EXPORT_SYMBOL_GPL(s5m_bulk_read); - -int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value) -{ - return regmap_write(s5m87xx->regmap, reg, value); -} -EXPORT_SYMBOL_GPL(s5m_reg_write); - -int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) -{ - return regmap_raw_write(s5m87xx->regmap, reg, buf, count); -} -EXPORT_SYMBOL_GPL(s5m_bulk_write); - -int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask) -{ - return regmap_update_bits(s5m87xx->regmap, reg, mask, val); -} -EXPORT_SYMBOL_GPL(s5m_reg_update); - -static struct regmap_config s5m_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -}; - -static int s5m87xx_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct s5m_platform_data *pdata = i2c->dev.platform_data; - struct s5m87xx_dev *s5m87xx; - int ret; - - s5m87xx = devm_kzalloc(&i2c->dev, sizeof(struct s5m87xx_dev), - GFP_KERNEL); - if (s5m87xx == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, s5m87xx); - s5m87xx->dev = &i2c->dev; - s5m87xx->i2c = i2c; - s5m87xx->irq = i2c->irq; - s5m87xx->type = id->driver_data; - - if (pdata) { - s5m87xx->device_type = pdata->device_type; - s5m87xx->ono = pdata->ono; - s5m87xx->irq_base = pdata->irq_base; - s5m87xx->wakeup = pdata->wakeup; - } - - s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config); - if (IS_ERR(s5m87xx->regmap)) { - ret = PTR_ERR(s5m87xx->regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); - goto err; - } - - s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); - i2c_set_clientdata(s5m87xx->rtc, s5m87xx); - - if (pdata && pdata->cfg_pmic_irq) - pdata->cfg_pmic_irq(); - - s5m_irq_init(s5m87xx); - - pm_runtime_set_active(s5m87xx->dev); - - switch (s5m87xx->device_type) { - case S5M8751X: - ret = mfd_add_devices(s5m87xx->dev, -1, s5m8751_devs, - ARRAY_SIZE(s5m8751_devs), NULL, 0); - break; - case S5M8763X: - ret = mfd_add_devices(s5m87xx->dev, -1, s5m8763_devs, - ARRAY_SIZE(s5m8763_devs), NULL, 0); - break; - case S5M8767X: - ret = mfd_add_devices(s5m87xx->dev, -1, s5m8767_devs, - ARRAY_SIZE(s5m8767_devs), NULL, 0); - break; - default: - /* If this happens the probe function is problem */ - BUG(); - } - - if (ret < 0) - goto err; - - return ret; - -err: - mfd_remove_devices(s5m87xx->dev); - s5m_irq_exit(s5m87xx); - i2c_unregister_device(s5m87xx->rtc); - regmap_exit(s5m87xx->regmap); - return ret; -} - -static int s5m87xx_i2c_remove(struct i2c_client *i2c) -{ - struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c); - - mfd_remove_devices(s5m87xx->dev); - s5m_irq_exit(s5m87xx); - i2c_unregister_device(s5m87xx->rtc); - regmap_exit(s5m87xx->regmap); - return 0; -} - -static const struct i2c_device_id s5m87xx_i2c_id[] = { - { "s5m87xx", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id); - -static struct i2c_driver s5m87xx_i2c_driver = { - .driver = { - .name = "s5m87xx", - .owner = THIS_MODULE, - }, - .probe = s5m87xx_i2c_probe, - .remove = s5m87xx_i2c_remove, - .id_table = s5m87xx_i2c_id, -}; - -static int __init s5m87xx_i2c_init(void) -{ - return i2c_add_driver(&s5m87xx_i2c_driver); -} - -subsys_initcall(s5m87xx_i2c_init); - -static void __exit s5m87xx_i2c_exit(void) -{ - i2c_del_driver(&s5m87xx_i2c_driver); -} -module_exit(s5m87xx_i2c_exit); - -MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); -MODULE_DESCRIPTION("Core support for the S5M MFD"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/s5m-irq.c b/ANDROID_3.4.5/drivers/mfd/s5m-irq.c deleted file mode 100644 index 02366760..00000000 --- a/ANDROID_3.4.5/drivers/mfd/s5m-irq.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * s5m-irq.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mfd/s5m87xx/s5m-core.h> - -struct s5m_irq_data { - int reg; - int mask; -}; - -static struct s5m_irq_data s5m8767_irqs[] = { - [S5M8767_IRQ_PWRR] = { - .reg = 1, - .mask = S5M8767_IRQ_PWRR_MASK, - }, - [S5M8767_IRQ_PWRF] = { - .reg = 1, - .mask = S5M8767_IRQ_PWRF_MASK, - }, - [S5M8767_IRQ_PWR1S] = { - .reg = 1, - .mask = S5M8767_IRQ_PWR1S_MASK, - }, - [S5M8767_IRQ_JIGR] = { - .reg = 1, - .mask = S5M8767_IRQ_JIGR_MASK, - }, - [S5M8767_IRQ_JIGF] = { - .reg = 1, - .mask = S5M8767_IRQ_JIGF_MASK, - }, - [S5M8767_IRQ_LOWBAT2] = { - .reg = 1, - .mask = S5M8767_IRQ_LOWBAT2_MASK, - }, - [S5M8767_IRQ_LOWBAT1] = { - .reg = 1, - .mask = S5M8767_IRQ_LOWBAT1_MASK, - }, - [S5M8767_IRQ_MRB] = { - .reg = 2, - .mask = S5M8767_IRQ_MRB_MASK, - }, - [S5M8767_IRQ_DVSOK2] = { - .reg = 2, - .mask = S5M8767_IRQ_DVSOK2_MASK, - }, - [S5M8767_IRQ_DVSOK3] = { - .reg = 2, - .mask = S5M8767_IRQ_DVSOK3_MASK, - }, - [S5M8767_IRQ_DVSOK4] = { - .reg = 2, - .mask = S5M8767_IRQ_DVSOK4_MASK, - }, - [S5M8767_IRQ_RTC60S] = { - .reg = 3, - .mask = S5M8767_IRQ_RTC60S_MASK, - }, - [S5M8767_IRQ_RTCA1] = { - .reg = 3, - .mask = S5M8767_IRQ_RTCA1_MASK, - }, - [S5M8767_IRQ_RTCA2] = { - .reg = 3, - .mask = S5M8767_IRQ_RTCA2_MASK, - }, - [S5M8767_IRQ_SMPL] = { - .reg = 3, - .mask = S5M8767_IRQ_SMPL_MASK, - }, - [S5M8767_IRQ_RTC1S] = { - .reg = 3, - .mask = S5M8767_IRQ_RTC1S_MASK, - }, - [S5M8767_IRQ_WTSR] = { - .reg = 3, - .mask = S5M8767_IRQ_WTSR_MASK, - }, -}; - -static struct s5m_irq_data s5m8763_irqs[] = { - [S5M8763_IRQ_DCINF] = { - .reg = 1, - .mask = S5M8763_IRQ_DCINF_MASK, - }, - [S5M8763_IRQ_DCINR] = { - .reg = 1, - .mask = S5M8763_IRQ_DCINR_MASK, - }, - [S5M8763_IRQ_JIGF] = { - .reg = 1, - .mask = S5M8763_IRQ_JIGF_MASK, - }, - [S5M8763_IRQ_JIGR] = { - .reg = 1, - .mask = S5M8763_IRQ_JIGR_MASK, - }, - [S5M8763_IRQ_PWRONF] = { - .reg = 1, - .mask = S5M8763_IRQ_PWRONF_MASK, - }, - [S5M8763_IRQ_PWRONR] = { - .reg = 1, - .mask = S5M8763_IRQ_PWRONR_MASK, - }, - [S5M8763_IRQ_WTSREVNT] = { - .reg = 2, - .mask = S5M8763_IRQ_WTSREVNT_MASK, - }, - [S5M8763_IRQ_SMPLEVNT] = { - .reg = 2, - .mask = S5M8763_IRQ_SMPLEVNT_MASK, - }, - [S5M8763_IRQ_ALARM1] = { - .reg = 2, - .mask = S5M8763_IRQ_ALARM1_MASK, - }, - [S5M8763_IRQ_ALARM0] = { - .reg = 2, - .mask = S5M8763_IRQ_ALARM0_MASK, - }, - [S5M8763_IRQ_ONKEY1S] = { - .reg = 3, - .mask = S5M8763_IRQ_ONKEY1S_MASK, - }, - [S5M8763_IRQ_TOPOFFR] = { - .reg = 3, - .mask = S5M8763_IRQ_TOPOFFR_MASK, - }, - [S5M8763_IRQ_DCINOVPR] = { - .reg = 3, - .mask = S5M8763_IRQ_DCINOVPR_MASK, - }, - [S5M8763_IRQ_CHGRSTF] = { - .reg = 3, - .mask = S5M8763_IRQ_CHGRSTF_MASK, - }, - [S5M8763_IRQ_DONER] = { - .reg = 3, - .mask = S5M8763_IRQ_DONER_MASK, - }, - [S5M8763_IRQ_CHGFAULT] = { - .reg = 3, - .mask = S5M8763_IRQ_CHGFAULT_MASK, - }, - [S5M8763_IRQ_LOBAT1] = { - .reg = 4, - .mask = S5M8763_IRQ_LOBAT1_MASK, - }, - [S5M8763_IRQ_LOBAT2] = { - .reg = 4, - .mask = S5M8763_IRQ_LOBAT2_MASK, - }, -}; - -static inline struct s5m_irq_data * -irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq) -{ - return &s5m8767_irqs[irq - s5m87xx->irq_base]; -} - -static void s5m8767_irq_lock(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - - mutex_lock(&s5m87xx->irqlock); -} - -static void s5m8767_irq_sync_unlock(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) { - if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) { - s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i]; - s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i, - s5m87xx->irq_masks_cur[i]); - } - } - - mutex_unlock(&s5m87xx->irqlock); -} - -static void s5m8767_irq_unmask(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx, - data->irq); - - s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; -} - -static void s5m8767_irq_mask(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx, - data->irq); - - s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; -} - -static struct irq_chip s5m8767_irq_chip = { - .name = "s5m8767", - .irq_bus_lock = s5m8767_irq_lock, - .irq_bus_sync_unlock = s5m8767_irq_sync_unlock, - .irq_mask = s5m8767_irq_mask, - .irq_unmask = s5m8767_irq_unmask, -}; - -static inline struct s5m_irq_data * -irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq) -{ - return &s5m8763_irqs[irq - s5m87xx->irq_base]; -} - -static void s5m8763_irq_lock(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - - mutex_lock(&s5m87xx->irqlock); -} - -static void s5m8763_irq_sync_unlock(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) { - if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) { - s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i]; - s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i, - s5m87xx->irq_masks_cur[i]); - } - } - - mutex_unlock(&s5m87xx->irqlock); -} - -static void s5m8763_irq_unmask(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx, - data->irq); - - s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; -} - -static void s5m8763_irq_mask(struct irq_data *data) -{ - struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); - struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx, - data->irq); - - s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; -} - -static struct irq_chip s5m8763_irq_chip = { - .name = "s5m8763", - .irq_bus_lock = s5m8763_irq_lock, - .irq_bus_sync_unlock = s5m8763_irq_sync_unlock, - .irq_mask = s5m8763_irq_mask, - .irq_unmask = s5m8763_irq_unmask, -}; - - -static irqreturn_t s5m8767_irq_thread(int irq, void *data) -{ - struct s5m87xx_dev *s5m87xx = data; - u8 irq_reg[NUM_IRQ_REGS-1]; - int ret; - int i; - - - ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1, - NUM_IRQ_REGS - 1, irq_reg); - if (ret < 0) { - dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n", - ret); - return IRQ_NONE; - } - - for (i = 0; i < NUM_IRQ_REGS - 1; i++) - irq_reg[i] &= ~s5m87xx->irq_masks_cur[i]; - - for (i = 0; i < S5M8767_IRQ_NR; i++) { - if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask) - handle_nested_irq(s5m87xx->irq_base + i); - } - - return IRQ_HANDLED; -} - -static irqreturn_t s5m8763_irq_thread(int irq, void *data) -{ - struct s5m87xx_dev *s5m87xx = data; - u8 irq_reg[NUM_IRQ_REGS]; - int ret; - int i; - - ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1, - NUM_IRQ_REGS, irq_reg); - if (ret < 0) { - dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n", - ret); - return IRQ_NONE; - } - - for (i = 0; i < NUM_IRQ_REGS; i++) - irq_reg[i] &= ~s5m87xx->irq_masks_cur[i]; - - for (i = 0; i < S5M8763_IRQ_NR; i++) { - if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask) - handle_nested_irq(s5m87xx->irq_base + i); - } - - return IRQ_HANDLED; -} - -int s5m_irq_resume(struct s5m87xx_dev *s5m87xx) -{ - if (s5m87xx->irq && s5m87xx->irq_base){ - switch (s5m87xx->device_type) { - case S5M8763X: - s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx); - break; - case S5M8767X: - s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx); - break; - default: - dev_err(s5m87xx->dev, - "Unknown device type %d\n", - s5m87xx->device_type); - return -EINVAL; - - } - } - return 0; -} - -int s5m_irq_init(struct s5m87xx_dev *s5m87xx) -{ - int i; - int cur_irq; - int ret = 0; - int type = s5m87xx->device_type; - - if (!s5m87xx->irq) { - dev_warn(s5m87xx->dev, - "No interrupt specified, no interrupts\n"); - s5m87xx->irq_base = 0; - return 0; - } - - if (!s5m87xx->irq_base) { - dev_err(s5m87xx->dev, - "No interrupt base specified, no interrupts\n"); - return 0; - } - - mutex_init(&s5m87xx->irqlock); - - switch (type) { - case S5M8763X: - for (i = 0; i < NUM_IRQ_REGS; i++) { - s5m87xx->irq_masks_cur[i] = 0xff; - s5m87xx->irq_masks_cache[i] = 0xff; - s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i, - 0xff); - } - - s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff); - s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff); - - for (i = 0; i < S5M8763_IRQ_NR; i++) { - cur_irq = i + s5m87xx->irq_base; - irq_set_chip_data(cur_irq, s5m87xx); - irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(s5m87xx->irq, NULL, - s5m8763_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "s5m87xx-irq", s5m87xx); - if (ret) { - dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", - s5m87xx->irq, ret); - return ret; - } - break; - case S5M8767X: - for (i = 0; i < NUM_IRQ_REGS - 1; i++) { - s5m87xx->irq_masks_cur[i] = 0xff; - s5m87xx->irq_masks_cache[i] = 0xff; - s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i, - 0xff); - } - for (i = 0; i < S5M8767_IRQ_NR; i++) { - cur_irq = i + s5m87xx->irq_base; - irq_set_chip_data(cur_irq, s5m87xx); - if (ret) { - dev_err(s5m87xx->dev, - "Failed to irq_set_chip_data %d: %d\n", - s5m87xx->irq, ret); - return ret; - } - - irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(s5m87xx->irq, NULL, - s5m8767_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "s5m87xx-irq", s5m87xx); - if (ret) { - dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", - s5m87xx->irq, ret); - return ret; - } - break; - default: - dev_err(s5m87xx->dev, - "Unknown device type %d\n", s5m87xx->device_type); - return -EINVAL; - } - - if (!s5m87xx->ono) - return 0; - - switch (type) { - case S5M8763X: - ret = request_threaded_irq(s5m87xx->ono, NULL, - s5m8763_irq_thread, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "s5m87xx-ono", - s5m87xx); - break; - case S5M8767X: - ret = request_threaded_irq(s5m87xx->ono, NULL, - s5m8767_irq_thread, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "s5m87xx-ono", s5m87xx); - break; - default: - ret = -EINVAL; - break; - } - - if (ret) { - dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", - s5m87xx->ono, ret); - return ret; - } - - return 0; -} - -void s5m_irq_exit(struct s5m87xx_dev *s5m87xx) -{ - if (s5m87xx->ono) - free_irq(s5m87xx->ono, s5m87xx); - - if (s5m87xx->irq) - free_irq(s5m87xx->irq, s5m87xx); -} diff --git a/ANDROID_3.4.5/drivers/mfd/sm501.c b/ANDROID_3.4.5/drivers/mfd/sm501.c deleted file mode 100644 index d927dd49..00000000 --- a/ANDROID_3.4.5/drivers/mfd/sm501.c +++ /dev/null @@ -1,1765 +0,0 @@ -/* linux/drivers/mfd/sm501.c - * - * Copyright (C) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * Vincent Sanders <vince@simtec.co.uk> - * - * 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. - * - * SM501 MFD driver -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/pci.h> -#include <linux/i2c-gpio.h> -#include <linux/slab.h> - -#include <linux/sm501.h> -#include <linux/sm501-regs.h> -#include <linux/serial_8250.h> - -#include <linux/io.h> - -struct sm501_device { - struct list_head list; - struct platform_device pdev; -}; - -struct sm501_gpio; - -#ifdef CONFIG_MFD_SM501_GPIO -#include <linux/gpio.h> - -struct sm501_gpio_chip { - struct gpio_chip gpio; - struct sm501_gpio *ourgpio; /* to get back to parent. */ - void __iomem *regbase; - void __iomem *control; /* address of control reg. */ -}; - -struct sm501_gpio { - struct sm501_gpio_chip low; - struct sm501_gpio_chip high; - spinlock_t lock; - - unsigned int registered : 1; - void __iomem *regs; - struct resource *regs_res; -}; -#else -struct sm501_gpio { - /* no gpio support, empty definition for sm501_devdata. */ -}; -#endif - -struct sm501_devdata { - spinlock_t reg_lock; - struct mutex clock_lock; - struct list_head devices; - struct sm501_gpio gpio; - - struct device *dev; - struct resource *io_res; - struct resource *mem_res; - struct resource *regs_claim; - struct sm501_platdata *platdata; - - - unsigned int in_suspend; - unsigned long pm_misc; - - int unit_power[20]; - unsigned int pdev_id; - unsigned int irq; - void __iomem *regs; - unsigned int rev; -}; - - -#define MHZ (1000 * 1000) - -#ifdef DEBUG -static const unsigned int div_tab[] = { - [0] = 1, - [1] = 2, - [2] = 4, - [3] = 8, - [4] = 16, - [5] = 32, - [6] = 64, - [7] = 128, - [8] = 3, - [9] = 6, - [10] = 12, - [11] = 24, - [12] = 48, - [13] = 96, - [14] = 192, - [15] = 384, - [16] = 5, - [17] = 10, - [18] = 20, - [19] = 40, - [20] = 80, - [21] = 160, - [22] = 320, - [23] = 604, -}; - -static unsigned long decode_div(unsigned long pll2, unsigned long val, - unsigned int lshft, unsigned int selbit, - unsigned long mask) -{ - if (val & selbit) - pll2 = 288 * MHZ; - - return pll2 / div_tab[(val >> lshft) & mask]; -} - -#define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x) - -/* sm501_dump_clk - * - * Print out the current clock configuration for the device -*/ - -static void sm501_dump_clk(struct sm501_devdata *sm) -{ - unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING); - unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK); - unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK); - unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL); - unsigned long sdclk0, sdclk1; - unsigned long pll2 = 0; - - switch (misct & 0x30) { - case 0x00: - pll2 = 336 * MHZ; - break; - case 0x10: - pll2 = 288 * MHZ; - break; - case 0x20: - pll2 = 240 * MHZ; - break; - case 0x30: - pll2 = 192 * MHZ; - break; - } - - sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ; - sdclk0 /= div_tab[((misct >> 8) & 0xf)]; - - sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ; - sdclk1 /= div_tab[((misct >> 16) & 0xf)]; - - dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n", - misct, pm0, pm1); - - dev_dbg(sm->dev, "PLL2 = %ld.%ld MHz (%ld), SDCLK0=%08lx, SDCLK1=%08lx\n", - fmt_freq(pll2), sdclk0, sdclk1); - - dev_dbg(sm->dev, "SDRAM: PM0=%ld, PM1=%ld\n", sdclk0, sdclk1); - - dev_dbg(sm->dev, "PM0[%c]: " - "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " - "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", - (pmc & 3 ) == 0 ? '*' : '-', - fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)), - fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)), - fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15)), - fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15))); - - dev_dbg(sm->dev, "PM1[%c]: " - "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " - "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", - (pmc & 3 ) == 1 ? '*' : '-', - fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31)), - fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15)), - fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15)), - fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15))); -} - -static void sm501_dump_regs(struct sm501_devdata *sm) -{ - void __iomem *regs = sm->regs; - - dev_info(sm->dev, "System Control %08x\n", - smc501_readl(regs + SM501_SYSTEM_CONTROL)); - dev_info(sm->dev, "Misc Control %08x\n", - smc501_readl(regs + SM501_MISC_CONTROL)); - dev_info(sm->dev, "GPIO Control Low %08x\n", - smc501_readl(regs + SM501_GPIO31_0_CONTROL)); - dev_info(sm->dev, "GPIO Control Hi %08x\n", - smc501_readl(regs + SM501_GPIO63_32_CONTROL)); - dev_info(sm->dev, "DRAM Control %08x\n", - smc501_readl(regs + SM501_DRAM_CONTROL)); - dev_info(sm->dev, "Arbitration Ctrl %08x\n", - smc501_readl(regs + SM501_ARBTRTN_CONTROL)); - dev_info(sm->dev, "Misc Timing %08x\n", - smc501_readl(regs + SM501_MISC_TIMING)); -} - -static void sm501_dump_gate(struct sm501_devdata *sm) -{ - dev_info(sm->dev, "CurrentGate %08x\n", - smc501_readl(sm->regs + SM501_CURRENT_GATE)); - dev_info(sm->dev, "CurrentClock %08x\n", - smc501_readl(sm->regs + SM501_CURRENT_CLOCK)); - dev_info(sm->dev, "PowerModeControl %08x\n", - smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL)); -} - -#else -static inline void sm501_dump_gate(struct sm501_devdata *sm) { } -static inline void sm501_dump_regs(struct sm501_devdata *sm) { } -static inline void sm501_dump_clk(struct sm501_devdata *sm) { } -#endif - -/* sm501_sync_regs - * - * ensure the -*/ - -static void sm501_sync_regs(struct sm501_devdata *sm) -{ - smc501_readl(sm->regs); -} - -static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay) -{ - /* during suspend/resume, we are currently not allowed to sleep, - * so change to using mdelay() instead of msleep() if we - * are in one of these paths */ - - if (sm->in_suspend) - mdelay(delay); - else - msleep(delay); -} - -/* sm501_misc_control - * - * alters the miscellaneous control parameters -*/ - -int sm501_misc_control(struct device *dev, - unsigned long set, unsigned long clear) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long misc; - unsigned long save; - unsigned long to; - - spin_lock_irqsave(&sm->reg_lock, save); - - misc = smc501_readl(sm->regs + SM501_MISC_CONTROL); - to = (misc & ~clear) | set; - - if (to != misc) { - smc501_writel(to, sm->regs + SM501_MISC_CONTROL); - sm501_sync_regs(sm); - - dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc); - } - - spin_unlock_irqrestore(&sm->reg_lock, save); - return to; -} - -EXPORT_SYMBOL_GPL(sm501_misc_control); - -/* sm501_modify_reg - * - * Modify a register in the SM501 which may be shared with other - * drivers. -*/ - -unsigned long sm501_modify_reg(struct device *dev, - unsigned long reg, - unsigned long set, - unsigned long clear) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long data; - unsigned long save; - - spin_lock_irqsave(&sm->reg_lock, save); - - data = smc501_readl(sm->regs + reg); - data |= set; - data &= ~clear; - - smc501_writel(data, sm->regs + reg); - sm501_sync_regs(sm); - - spin_unlock_irqrestore(&sm->reg_lock, save); - - return data; -} - -EXPORT_SYMBOL_GPL(sm501_modify_reg); - -/* sm501_unit_power - * - * alters the power active gate to set specific units on or off - */ - -int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long mode; - unsigned long gate; - unsigned long clock; - - mutex_lock(&sm->clock_lock); - - mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL); - gate = smc501_readl(sm->regs + SM501_CURRENT_GATE); - clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK); - - mode &= 3; /* get current power mode */ - - if (unit >= ARRAY_SIZE(sm->unit_power)) { - dev_err(dev, "%s: bad unit %d\n", __func__, unit); - goto already; - } - - dev_dbg(sm->dev, "%s: unit %d, cur %d, to %d\n", __func__, unit, - sm->unit_power[unit], to); - - if (to == 0 && sm->unit_power[unit] == 0) { - dev_err(sm->dev, "unit %d is already shutdown\n", unit); - goto already; - } - - sm->unit_power[unit] += to ? 1 : -1; - to = sm->unit_power[unit] ? 1 : 0; - - if (to) { - if (gate & (1 << unit)) - goto already; - gate |= (1 << unit); - } else { - if (!(gate & (1 << unit))) - goto already; - gate &= ~(1 << unit); - } - - switch (mode) { - case 1: - smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); - smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); - mode = 0; - break; - case 2: - case 0: - smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); - smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); - mode = 1; - break; - - default: - gate = -1; - goto already; - } - - smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); - sm501_sync_regs(sm); - - dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", - gate, clock, mode); - - sm501_mdelay(sm, 16); - - already: - mutex_unlock(&sm->clock_lock); - return gate; -} - -EXPORT_SYMBOL_GPL(sm501_unit_power); - -/* clock value structure. */ -struct sm501_clock { - unsigned long mclk; - int divider; - int shift; - unsigned int m, n, k; -}; - -/* sm501_calc_clock - * - * Calculates the nearest discrete clock frequency that - * can be achieved with the specified input clock. - * the maximum divisor is 3 or 5 - */ - -static int sm501_calc_clock(unsigned long freq, - struct sm501_clock *clock, - int max_div, - unsigned long mclk, - long *best_diff) -{ - int ret = 0; - int divider; - int shift; - long diff; - - /* try dividers 1 and 3 for CRT and for panel, - try divider 5 for panel only.*/ - - for (divider = 1; divider <= max_div; divider += 2) { - /* try all 8 shift values.*/ - for (shift = 0; shift < 8; shift++) { - /* Calculate difference to requested clock */ - diff = DIV_ROUND_CLOSEST(mclk, divider << shift) - freq; - if (diff < 0) - diff = -diff; - - /* If it is less than the current, use it */ - if (diff < *best_diff) { - *best_diff = diff; - - clock->mclk = mclk; - clock->divider = divider; - clock->shift = shift; - ret = 1; - } - } - } - - return ret; -} - -/* sm501_calc_pll - * - * Calculates the nearest discrete clock frequency that can be - * achieved using the programmable PLL. - * the maximum divisor is 3 or 5 - */ - -static unsigned long sm501_calc_pll(unsigned long freq, - struct sm501_clock *clock, - int max_div) -{ - unsigned long mclk; - unsigned int m, n, k; - long best_diff = 999999999; - - /* - * The SM502 datasheet doesn't specify the min/max values for M and N. - * N = 1 at least doesn't work in practice. - */ - for (m = 2; m <= 255; m++) { - for (n = 2; n <= 127; n++) { - for (k = 0; k <= 1; k++) { - mclk = (24000000UL * m / n) >> k; - - if (sm501_calc_clock(freq, clock, max_div, - mclk, &best_diff)) { - clock->m = m; - clock->n = n; - clock->k = k; - } - } - } - } - - /* Return best clock. */ - return clock->mclk / (clock->divider << clock->shift); -} - -/* sm501_select_clock - * - * Calculates the nearest discrete clock frequency that can be - * achieved using the 288MHz and 336MHz PLLs. - * the maximum divisor is 3 or 5 - */ - -static unsigned long sm501_select_clock(unsigned long freq, - struct sm501_clock *clock, - int max_div) -{ - unsigned long mclk; - long best_diff = 999999999; - - /* Try 288MHz and 336MHz clocks. */ - for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) { - sm501_calc_clock(freq, clock, max_div, mclk, &best_diff); - } - - /* Return best clock. */ - return clock->mclk / (clock->divider << clock->shift); -} - -/* sm501_set_clock - * - * set one of the four clock sources to the closest available frequency to - * the one specified -*/ - -unsigned long sm501_set_clock(struct device *dev, - int clksrc, - unsigned long req_freq) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL); - unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE); - unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK); - unsigned char reg; - unsigned int pll_reg = 0; - unsigned long sm501_freq; /* the actual frequency achieved */ - - struct sm501_clock to; - - /* find achivable discrete frequency and setup register value - * accordingly, V2XCLK, MCLK and M1XCLK are the same P2XCLK - * has an extra bit for the divider */ - - switch (clksrc) { - case SM501_CLOCK_P2XCLK: - /* This clock is divided in half so to achieve the - * requested frequency the value must be multiplied by - * 2. This clock also has an additional pre divisor */ - - if (sm->rev >= 0xC0) { - /* SM502 -> use the programmable PLL */ - sm501_freq = (sm501_calc_pll(2 * req_freq, - &to, 5) / 2); - reg = to.shift & 0x07;/* bottom 3 bits are shift */ - if (to.divider == 3) - reg |= 0x08; /* /3 divider required */ - else if (to.divider == 5) - reg |= 0x10; /* /5 divider required */ - reg |= 0x40; /* select the programmable PLL */ - pll_reg = 0x20000 | (to.k << 15) | (to.n << 8) | to.m; - } else { - sm501_freq = (sm501_select_clock(2 * req_freq, - &to, 5) / 2); - reg = to.shift & 0x07;/* bottom 3 bits are shift */ - if (to.divider == 3) - reg |= 0x08; /* /3 divider required */ - else if (to.divider == 5) - reg |= 0x10; /* /5 divider required */ - if (to.mclk != 288000000) - reg |= 0x20; /* which mclk pll is source */ - } - break; - - case SM501_CLOCK_V2XCLK: - /* This clock is divided in half so to achieve the - * requested frequency the value must be multiplied by 2. */ - - sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2); - reg=to.shift & 0x07; /* bottom 3 bits are shift */ - if (to.divider == 3) - reg |= 0x08; /* /3 divider required */ - if (to.mclk != 288000000) - reg |= 0x10; /* which mclk pll is source */ - break; - - case SM501_CLOCK_MCLK: - case SM501_CLOCK_M1XCLK: - /* These clocks are the same and not further divided */ - - sm501_freq = sm501_select_clock( req_freq, &to, 3); - reg=to.shift & 0x07; /* bottom 3 bits are shift */ - if (to.divider == 3) - reg |= 0x08; /* /3 divider required */ - if (to.mclk != 288000000) - reg |= 0x10; /* which mclk pll is source */ - break; - - default: - return 0; /* this is bad */ - } - - mutex_lock(&sm->clock_lock); - - mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL); - gate = smc501_readl(sm->regs + SM501_CURRENT_GATE); - clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK); - - clock = clock & ~(0xFF << clksrc); - clock |= reg<<clksrc; - - mode &= 3; /* find current mode */ - - switch (mode) { - case 1: - smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); - smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); - mode = 0; - break; - case 2: - case 0: - smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); - smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); - mode = 1; - break; - - default: - mutex_unlock(&sm->clock_lock); - return -1; - } - - smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); - - if (pll_reg) - smc501_writel(pll_reg, - sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL); - - sm501_sync_regs(sm); - - dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", - gate, clock, mode); - - sm501_mdelay(sm, 16); - mutex_unlock(&sm->clock_lock); - - sm501_dump_clk(sm); - - return sm501_freq; -} - -EXPORT_SYMBOL_GPL(sm501_set_clock); - -/* sm501_find_clock - * - * finds the closest available frequency for a given clock -*/ - -unsigned long sm501_find_clock(struct device *dev, - int clksrc, - unsigned long req_freq) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long sm501_freq; /* the frequency achieveable by the 501 */ - struct sm501_clock to; - - switch (clksrc) { - case SM501_CLOCK_P2XCLK: - if (sm->rev >= 0xC0) { - /* SM502 -> use the programmable PLL */ - sm501_freq = (sm501_calc_pll(2 * req_freq, - &to, 5) / 2); - } else { - sm501_freq = (sm501_select_clock(2 * req_freq, - &to, 5) / 2); - } - break; - - case SM501_CLOCK_V2XCLK: - sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2); - break; - - case SM501_CLOCK_MCLK: - case SM501_CLOCK_M1XCLK: - sm501_freq = sm501_select_clock(req_freq, &to, 3); - break; - - default: - sm501_freq = 0; /* error */ - } - - return sm501_freq; -} - -EXPORT_SYMBOL_GPL(sm501_find_clock); - -static struct sm501_device *to_sm_device(struct platform_device *pdev) -{ - return container_of(pdev, struct sm501_device, pdev); -} - -/* sm501_device_release - * - * A release function for the platform devices we create to allow us to - * free any items we allocated -*/ - -static void sm501_device_release(struct device *dev) -{ - kfree(to_sm_device(to_platform_device(dev))); -} - -/* sm501_create_subdev - * - * Create a skeleton platform device with resources for passing to a - * sub-driver -*/ - -static struct platform_device * -sm501_create_subdev(struct sm501_devdata *sm, char *name, - unsigned int res_count, unsigned int platform_data_size) -{ - struct sm501_device *smdev; - - smdev = kzalloc(sizeof(struct sm501_device) + - (sizeof(struct resource) * res_count) + - platform_data_size, GFP_KERNEL); - if (!smdev) - return NULL; - - smdev->pdev.dev.release = sm501_device_release; - - smdev->pdev.name = name; - smdev->pdev.id = sm->pdev_id; - smdev->pdev.dev.parent = sm->dev; - - if (res_count) { - smdev->pdev.resource = (struct resource *)(smdev+1); - smdev->pdev.num_resources = res_count; - } - if (platform_data_size) - smdev->pdev.dev.platform_data = (void *)(smdev+1); - - return &smdev->pdev; -} - -/* sm501_register_device - * - * Register a platform device created with sm501_create_subdev() -*/ - -static int sm501_register_device(struct sm501_devdata *sm, - struct platform_device *pdev) -{ - struct sm501_device *smdev = to_sm_device(pdev); - int ptr; - int ret; - - for (ptr = 0; ptr < pdev->num_resources; ptr++) { - printk(KERN_DEBUG "%s[%d] %pR\n", - pdev->name, ptr, &pdev->resource[ptr]); - } - - ret = platform_device_register(pdev); - - if (ret >= 0) { - dev_dbg(sm->dev, "registered %s\n", pdev->name); - list_add_tail(&smdev->list, &sm->devices); - } else - dev_err(sm->dev, "error registering %s (%d)\n", - pdev->name, ret); - - return ret; -} - -/* sm501_create_subio - * - * Fill in an IO resource for a sub device -*/ - -static void sm501_create_subio(struct sm501_devdata *sm, - struct resource *res, - resource_size_t offs, - resource_size_t size) -{ - res->flags = IORESOURCE_MEM; - res->parent = sm->io_res; - res->start = sm->io_res->start + offs; - res->end = res->start + size - 1; -} - -/* sm501_create_mem - * - * Fill in an MEM resource for a sub device -*/ - -static void sm501_create_mem(struct sm501_devdata *sm, - struct resource *res, - resource_size_t *offs, - resource_size_t size) -{ - *offs -= size; /* adjust memory size */ - - res->flags = IORESOURCE_MEM; - res->parent = sm->mem_res; - res->start = sm->mem_res->start + *offs; - res->end = res->start + size - 1; -} - -/* sm501_create_irq - * - * Fill in an IRQ resource for a sub device -*/ - -static void sm501_create_irq(struct sm501_devdata *sm, - struct resource *res) -{ - res->flags = IORESOURCE_IRQ; - res->parent = NULL; - res->start = res->end = sm->irq; -} - -static int sm501_register_usbhost(struct sm501_devdata *sm, - resource_size_t *mem_avail) -{ - struct platform_device *pdev; - - pdev = sm501_create_subdev(sm, "sm501-usb", 3, 0); - if (!pdev) - return -ENOMEM; - - sm501_create_subio(sm, &pdev->resource[0], 0x40000, 0x20000); - sm501_create_mem(sm, &pdev->resource[1], mem_avail, 256*1024); - sm501_create_irq(sm, &pdev->resource[2]); - - return sm501_register_device(sm, pdev); -} - -static void sm501_setup_uart_data(struct sm501_devdata *sm, - struct plat_serial8250_port *uart_data, - unsigned int offset) -{ - uart_data->membase = sm->regs + offset; - uart_data->mapbase = sm->io_res->start + offset; - uart_data->iotype = UPIO_MEM; - uart_data->irq = sm->irq; - uart_data->flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; - uart_data->regshift = 2; - uart_data->uartclk = (9600 * 16); -} - -static int sm501_register_uart(struct sm501_devdata *sm, int devices) -{ - struct platform_device *pdev; - struct plat_serial8250_port *uart_data; - - pdev = sm501_create_subdev(sm, "serial8250", 0, - sizeof(struct plat_serial8250_port) * 3); - if (!pdev) - return -ENOMEM; - - uart_data = pdev->dev.platform_data; - - if (devices & SM501_USE_UART0) { - sm501_setup_uart_data(sm, uart_data++, 0x30000); - sm501_unit_power(sm->dev, SM501_GATE_UART0, 1); - sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 12, 0); - sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x01e0, 0); - } - if (devices & SM501_USE_UART1) { - sm501_setup_uart_data(sm, uart_data++, 0x30020); - sm501_unit_power(sm->dev, SM501_GATE_UART1, 1); - sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 13, 0); - sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x1e00, 0); - } - - pdev->id = PLAT8250_DEV_SM501; - - return sm501_register_device(sm, pdev); -} - -static int sm501_register_display(struct sm501_devdata *sm, - resource_size_t *mem_avail) -{ - struct platform_device *pdev; - - pdev = sm501_create_subdev(sm, "sm501-fb", 4, 0); - if (!pdev) - return -ENOMEM; - - sm501_create_subio(sm, &pdev->resource[0], 0x80000, 0x10000); - sm501_create_subio(sm, &pdev->resource[1], 0x100000, 0x50000); - sm501_create_mem(sm, &pdev->resource[2], mem_avail, *mem_avail); - sm501_create_irq(sm, &pdev->resource[3]); - - return sm501_register_device(sm, pdev); -} - -#ifdef CONFIG_MFD_SM501_GPIO - -static inline struct sm501_gpio_chip *to_sm501_gpio(struct gpio_chip *gc) -{ - return container_of(gc, struct sm501_gpio_chip, gpio); -} - -static inline struct sm501_devdata *sm501_gpio_to_dev(struct sm501_gpio *gpio) -{ - return container_of(gpio, struct sm501_devdata, gpio); -} - -static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset) - -{ - struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip); - unsigned long result; - - result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW); - result >>= offset; - - return result & 1UL; -} - -static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip, - unsigned long bit) -{ - unsigned long ctrl; - - /* check and modify if this pin is not set as gpio. */ - - if (smc501_readl(smchip->control) & bit) { - dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev, - "changing mode of gpio, bit %08lx\n", bit); - - ctrl = smc501_readl(smchip->control); - ctrl &= ~bit; - smc501_writel(ctrl, smchip->control); - - sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio)); - } -} - -static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value) - -{ - struct sm501_gpio_chip *smchip = to_sm501_gpio(chip); - struct sm501_gpio *smgpio = smchip->ourgpio; - unsigned long bit = 1 << offset; - void __iomem *regs = smchip->regbase; - unsigned long save; - unsigned long val; - - dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n", - __func__, chip, offset); - - spin_lock_irqsave(&smgpio->lock, save); - - val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit; - if (value) - val |= bit; - smc501_writel(val, regs); - - sm501_sync_regs(sm501_gpio_to_dev(smgpio)); - sm501_gpio_ensure_gpio(smchip, bit); - - spin_unlock_irqrestore(&smgpio->lock, save); -} - -static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset) -{ - struct sm501_gpio_chip *smchip = to_sm501_gpio(chip); - struct sm501_gpio *smgpio = smchip->ourgpio; - void __iomem *regs = smchip->regbase; - unsigned long bit = 1 << offset; - unsigned long save; - unsigned long ddr; - - dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n", - __func__, chip, offset); - - spin_lock_irqsave(&smgpio->lock, save); - - ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW); - smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW); - - sm501_sync_regs(sm501_gpio_to_dev(smgpio)); - sm501_gpio_ensure_gpio(smchip, bit); - - spin_unlock_irqrestore(&smgpio->lock, save); - - return 0; -} - -static int sm501_gpio_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct sm501_gpio_chip *smchip = to_sm501_gpio(chip); - struct sm501_gpio *smgpio = smchip->ourgpio; - unsigned long bit = 1 << offset; - void __iomem *regs = smchip->regbase; - unsigned long save; - unsigned long val; - unsigned long ddr; - - dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d,%d)\n", - __func__, chip, offset, value); - - spin_lock_irqsave(&smgpio->lock, save); - - val = smc501_readl(regs + SM501_GPIO_DATA_LOW); - if (value) - val |= bit; - else - val &= ~bit; - smc501_writel(val, regs); - - ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW); - smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW); - - sm501_sync_regs(sm501_gpio_to_dev(smgpio)); - smc501_writel(val, regs + SM501_GPIO_DATA_LOW); - - sm501_sync_regs(sm501_gpio_to_dev(smgpio)); - spin_unlock_irqrestore(&smgpio->lock, save); - - return 0; -} - -static struct gpio_chip gpio_chip_template = { - .ngpio = 32, - .direction_input = sm501_gpio_input, - .direction_output = sm501_gpio_output, - .set = sm501_gpio_set, - .get = sm501_gpio_get, -}; - -static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm, - struct sm501_gpio *gpio, - struct sm501_gpio_chip *chip) -{ - struct sm501_platdata *pdata = sm->platdata; - struct gpio_chip *gchip = &chip->gpio; - int base = pdata->gpio_base; - - chip->gpio = gpio_chip_template; - - if (chip == &gpio->high) { - if (base > 0) - base += 32; - chip->regbase = gpio->regs + SM501_GPIO_DATA_HIGH; - chip->control = sm->regs + SM501_GPIO63_32_CONTROL; - gchip->label = "SM501-HIGH"; - } else { - chip->regbase = gpio->regs + SM501_GPIO_DATA_LOW; - chip->control = sm->regs + SM501_GPIO31_0_CONTROL; - gchip->label = "SM501-LOW"; - } - - gchip->base = base; - chip->ourgpio = gpio; - - return gpiochip_add(gchip); -} - -static int __devinit sm501_register_gpio(struct sm501_devdata *sm) -{ - struct sm501_gpio *gpio = &sm->gpio; - resource_size_t iobase = sm->io_res->start + SM501_GPIO; - int ret; - int tmp; - - dev_dbg(sm->dev, "registering gpio block %08llx\n", - (unsigned long long)iobase); - - spin_lock_init(&gpio->lock); - - gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio"); - if (gpio->regs_res == NULL) { - dev_err(sm->dev, "gpio: failed to request region\n"); - return -ENXIO; - } - - gpio->regs = ioremap(iobase, 0x20); - if (gpio->regs == NULL) { - dev_err(sm->dev, "gpio: failed to remap registers\n"); - ret = -ENXIO; - goto err_claimed; - } - - /* Register both our chips. */ - - ret = sm501_gpio_register_chip(sm, gpio, &gpio->low); - if (ret) { - dev_err(sm->dev, "failed to add low chip\n"); - goto err_mapped; - } - - ret = sm501_gpio_register_chip(sm, gpio, &gpio->high); - if (ret) { - dev_err(sm->dev, "failed to add high chip\n"); - goto err_low_chip; - } - - gpio->registered = 1; - - return 0; - - err_low_chip: - tmp = gpiochip_remove(&gpio->low.gpio); - if (tmp) { - dev_err(sm->dev, "cannot remove low chip, cannot tidy up\n"); - return ret; - } - - err_mapped: - iounmap(gpio->regs); - - err_claimed: - release_resource(gpio->regs_res); - kfree(gpio->regs_res); - - return ret; -} - -static void sm501_gpio_remove(struct sm501_devdata *sm) -{ - struct sm501_gpio *gpio = &sm->gpio; - int ret; - - if (!sm->gpio.registered) - return; - - ret = gpiochip_remove(&gpio->low.gpio); - if (ret) - dev_err(sm->dev, "cannot remove low chip, cannot tidy up\n"); - - ret = gpiochip_remove(&gpio->high.gpio); - if (ret) - dev_err(sm->dev, "cannot remove high chip, cannot tidy up\n"); - - iounmap(gpio->regs); - release_resource(gpio->regs_res); - kfree(gpio->regs_res); -} - -static inline int sm501_gpio_pin2nr(struct sm501_devdata *sm, unsigned int pin) -{ - struct sm501_gpio *gpio = &sm->gpio; - int base = (pin < 32) ? gpio->low.gpio.base : gpio->high.gpio.base; - - return (pin % 32) + base; -} - -static inline int sm501_gpio_isregistered(struct sm501_devdata *sm) -{ - return sm->gpio.registered; -} -#else -static inline int sm501_register_gpio(struct sm501_devdata *sm) -{ - return 0; -} - -static inline void sm501_gpio_remove(struct sm501_devdata *sm) -{ -} - -static inline int sm501_gpio_pin2nr(struct sm501_devdata *sm, unsigned int pin) -{ - return -1; -} - -static inline int sm501_gpio_isregistered(struct sm501_devdata *sm) -{ - return 0; -} -#endif - -static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, - struct sm501_platdata_gpio_i2c *iic) -{ - struct i2c_gpio_platform_data *icd; - struct platform_device *pdev; - - pdev = sm501_create_subdev(sm, "i2c-gpio", 0, - sizeof(struct i2c_gpio_platform_data)); - if (!pdev) - return -ENOMEM; - - icd = pdev->dev.platform_data; - - /* We keep the pin_sda and pin_scl fields relative in case the - * same platform data is passed to >1 SM501. - */ - - icd->sda_pin = sm501_gpio_pin2nr(sm, iic->pin_sda); - icd->scl_pin = sm501_gpio_pin2nr(sm, iic->pin_scl); - icd->timeout = iic->timeout; - icd->udelay = iic->udelay; - - /* note, we can't use either of the pin numbers, as the i2c-gpio - * driver uses the platform.id field to generate the bus number - * to register with the i2c core; The i2c core doesn't have enough - * entries to deal with anything we currently use. - */ - - pdev->id = iic->bus_num; - - dev_info(sm->dev, "registering i2c-%d: sda=%d (%d), scl=%d (%d)\n", - iic->bus_num, - icd->sda_pin, iic->pin_sda, icd->scl_pin, iic->pin_scl); - - return sm501_register_device(sm, pdev); -} - -static int sm501_register_gpio_i2c(struct sm501_devdata *sm, - struct sm501_platdata *pdata) -{ - struct sm501_platdata_gpio_i2c *iic = pdata->gpio_i2c; - int index; - int ret; - - for (index = 0; index < pdata->gpio_i2c_nr; index++, iic++) { - ret = sm501_register_gpio_i2c_instance(sm, iic); - if (ret < 0) - return ret; - } - - return 0; -} - -/* sm501_dbg_regs - * - * Debug attribute to attach to parent device to show core registers -*/ - -static ssize_t sm501_dbg_regs(struct device *dev, - struct device_attribute *attr, char *buff) -{ - struct sm501_devdata *sm = dev_get_drvdata(dev) ; - unsigned int reg; - char *ptr = buff; - int ret; - - for (reg = 0x00; reg < 0x70; reg += 4) { - ret = sprintf(ptr, "%08x = %08x\n", - reg, smc501_readl(sm->regs + reg)); - ptr += ret; - } - - return ptr - buff; -} - - -static DEVICE_ATTR(dbg_regs, 0666, sm501_dbg_regs, NULL); - -/* sm501_init_reg - * - * Helper function for the init code to setup a register - * - * clear the bits which are set in r->mask, and then set - * the bits set in r->set. -*/ - -static inline void sm501_init_reg(struct sm501_devdata *sm, - unsigned long reg, - struct sm501_reg_init *r) -{ - unsigned long tmp; - - tmp = smc501_readl(sm->regs + reg); - tmp &= ~r->mask; - tmp |= r->set; - smc501_writel(tmp, sm->regs + reg); -} - -/* sm501_init_regs - * - * Setup core register values -*/ - -static void sm501_init_regs(struct sm501_devdata *sm, - struct sm501_initdata *init) -{ - sm501_misc_control(sm->dev, - init->misc_control.set, - init->misc_control.mask); - - sm501_init_reg(sm, SM501_MISC_TIMING, &init->misc_timing); - sm501_init_reg(sm, SM501_GPIO31_0_CONTROL, &init->gpio_low); - sm501_init_reg(sm, SM501_GPIO63_32_CONTROL, &init->gpio_high); - - if (init->m1xclk) { - dev_info(sm->dev, "setting M1XCLK to %ld\n", init->m1xclk); - sm501_set_clock(sm->dev, SM501_CLOCK_M1XCLK, init->m1xclk); - } - - if (init->mclk) { - dev_info(sm->dev, "setting MCLK to %ld\n", init->mclk); - sm501_set_clock(sm->dev, SM501_CLOCK_MCLK, init->mclk); - } - -} - -/* Check the PLL sources for the M1CLK and M1XCLK - * - * If the M1CLK and M1XCLKs are not sourced from the same PLL, then - * there is a risk (see errata AB-5) that the SM501 will cease proper - * function. If this happens, then it is likely the SM501 will - * hang the system. -*/ - -static int sm501_check_clocks(struct sm501_devdata *sm) -{ - unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK); - unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC); - unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC); - - return ((msrc == 0 && m1src != 0) || (msrc != 0 && m1src == 0)); -} - -static unsigned int sm501_mem_local[] = { - [0] = 4*1024*1024, - [1] = 8*1024*1024, - [2] = 16*1024*1024, - [3] = 32*1024*1024, - [4] = 64*1024*1024, - [5] = 2*1024*1024, -}; - -/* sm501_init_dev - * - * Common init code for an SM501 -*/ - -static int __devinit sm501_init_dev(struct sm501_devdata *sm) -{ - struct sm501_initdata *idata; - struct sm501_platdata *pdata; - resource_size_t mem_avail; - unsigned long dramctrl; - unsigned long devid; - int ret; - - mutex_init(&sm->clock_lock); - spin_lock_init(&sm->reg_lock); - - INIT_LIST_HEAD(&sm->devices); - - devid = smc501_readl(sm->regs + SM501_DEVICEID); - - if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) { - dev_err(sm->dev, "incorrect device id %08lx\n", devid); - return -EINVAL; - } - - /* disable irqs */ - smc501_writel(0, sm->regs + SM501_IRQ_MASK); - - dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL); - mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7]; - - dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", - sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq); - - sm->rev = devid & SM501_DEVICEID_REVMASK; - - sm501_dump_gate(sm); - - ret = device_create_file(sm->dev, &dev_attr_dbg_regs); - if (ret) - dev_err(sm->dev, "failed to create debug regs file\n"); - - sm501_dump_clk(sm); - - /* check to see if we have some device initialisation */ - - pdata = sm->platdata; - idata = pdata ? pdata->init : NULL; - - if (idata) { - sm501_init_regs(sm, idata); - - if (idata->devices & SM501_USE_USB_HOST) - sm501_register_usbhost(sm, &mem_avail); - if (idata->devices & (SM501_USE_UART0 | SM501_USE_UART1)) - sm501_register_uart(sm, idata->devices); - if (idata->devices & SM501_USE_GPIO) - sm501_register_gpio(sm); - } - - if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { - if (!sm501_gpio_isregistered(sm)) - dev_err(sm->dev, "no gpio available for i2c gpio.\n"); - else - sm501_register_gpio_i2c(sm, pdata); - } - - ret = sm501_check_clocks(sm); - if (ret) { - dev_err(sm->dev, "M1X and M clocks sourced from different " - "PLLs\n"); - return -EINVAL; - } - - /* always create a framebuffer */ - sm501_register_display(sm, &mem_avail); - - return 0; -} - -static int __devinit sm501_plat_probe(struct platform_device *dev) -{ - struct sm501_devdata *sm; - int ret; - - sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); - if (sm == NULL) { - dev_err(&dev->dev, "no memory for device data\n"); - ret = -ENOMEM; - goto err1; - } - - sm->dev = &dev->dev; - sm->pdev_id = dev->id; - sm->platdata = dev->dev.platform_data; - - ret = platform_get_irq(dev, 0); - if (ret < 0) { - dev_err(&dev->dev, "failed to get irq resource\n"); - goto err_res; - } - sm->irq = ret; - - sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); - sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); - - if (sm->io_res == NULL || sm->mem_res == NULL) { - dev_err(&dev->dev, "failed to get IO resource\n"); - ret = -ENOENT; - goto err_res; - } - - sm->regs_claim = request_mem_region(sm->io_res->start, - 0x100, "sm501"); - - if (sm->regs_claim == NULL) { - dev_err(&dev->dev, "cannot claim registers\n"); - ret = -EBUSY; - goto err_res; - } - - platform_set_drvdata(dev, sm); - - sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res)); - - if (sm->regs == NULL) { - dev_err(&dev->dev, "cannot remap registers\n"); - ret = -EIO; - goto err_claim; - } - - return sm501_init_dev(sm); - - err_claim: - release_resource(sm->regs_claim); - kfree(sm->regs_claim); - err_res: - kfree(sm); - err1: - return ret; - -} - -#ifdef CONFIG_PM - -/* power management support */ - -static void sm501_set_power(struct sm501_devdata *sm, int on) -{ - struct sm501_platdata *pd = sm->platdata; - - if (pd == NULL) - return; - - if (pd->get_power) { - if (pd->get_power(sm->dev) == on) { - dev_dbg(sm->dev, "is already %d\n", on); - return; - } - } - - if (pd->set_power) { - dev_dbg(sm->dev, "setting power to %d\n", on); - - pd->set_power(sm->dev, on); - sm501_mdelay(sm, 10); - } -} - -static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct sm501_devdata *sm = platform_get_drvdata(pdev); - - sm->in_suspend = 1; - sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL); - - sm501_dump_regs(sm); - - if (sm->platdata) { - if (sm->platdata->flags & SM501_FLAG_SUSPEND_OFF) - sm501_set_power(sm, 0); - } - - return 0; -} - -static int sm501_plat_resume(struct platform_device *pdev) -{ - struct sm501_devdata *sm = platform_get_drvdata(pdev); - - sm501_set_power(sm, 1); - - sm501_dump_regs(sm); - sm501_dump_gate(sm); - sm501_dump_clk(sm); - - /* check to see if we are in the same state as when suspended */ - - if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) { - dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n"); - smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL); - - /* our suspend causes the controller state to change, - * either by something attempting setup, power loss, - * or an external reset event on power change */ - - if (sm->platdata && sm->platdata->init) { - sm501_init_regs(sm, sm->platdata->init); - } - } - - /* dump our state from resume */ - - sm501_dump_regs(sm); - sm501_dump_clk(sm); - - sm->in_suspend = 0; - - return 0; -} -#else -#define sm501_plat_suspend NULL -#define sm501_plat_resume NULL -#endif - -/* Initialisation data for PCI devices */ - -static struct sm501_initdata sm501_pci_initdata = { - .gpio_high = { - .set = 0x3F000000, /* 24bit panel */ - .mask = 0x0, - }, - .misc_timing = { - .set = 0x010100, /* SDRAM timing */ - .mask = 0x1F1F00, - }, - .misc_control = { - .set = SM501_MISC_PNL_24BIT, - .mask = 0, - }, - - .devices = SM501_USE_ALL, - - /* Errata AB-3 says that 72MHz is the fastest available - * for 33MHZ PCI with proper bus-mastering operation */ - - .mclk = 72 * MHZ, - .m1xclk = 144 * MHZ, -}; - -static struct sm501_platdata_fbsub sm501_pdata_fbsub = { - .flags = (SM501FB_FLAG_USE_INIT_MODE | - SM501FB_FLAG_USE_HWCURSOR | - SM501FB_FLAG_USE_HWACCEL | - SM501FB_FLAG_DISABLE_AT_EXIT), -}; - -static struct sm501_platdata_fb sm501_fb_pdata = { - .fb_route = SM501_FB_OWN, - .fb_crt = &sm501_pdata_fbsub, - .fb_pnl = &sm501_pdata_fbsub, -}; - -static struct sm501_platdata sm501_pci_platdata = { - .init = &sm501_pci_initdata, - .fb = &sm501_fb_pdata, - .gpio_base = -1, -}; - -static int __devinit sm501_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct sm501_devdata *sm; - int err; - - sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); - if (sm == NULL) { - dev_err(&dev->dev, "no memory for device data\n"); - err = -ENOMEM; - goto err1; - } - - /* set a default set of platform data */ - dev->dev.platform_data = sm->platdata = &sm501_pci_platdata; - - /* set a hopefully unique id for our child platform devices */ - sm->pdev_id = 32 + dev->devfn; - - pci_set_drvdata(dev, sm); - - err = pci_enable_device(dev); - if (err) { - dev_err(&dev->dev, "cannot enable device\n"); - goto err2; - } - - sm->dev = &dev->dev; - sm->irq = dev->irq; - -#ifdef __BIG_ENDIAN - /* if the system is big-endian, we most probably have a - * translation in the IO layer making the PCI bus little endian - * so make the framebuffer swapped pixels */ - - sm501_fb_pdata.flags |= SM501_FBPD_SWAP_FB_ENDIAN; -#endif - - /* check our resources */ - - if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM)) { - dev_err(&dev->dev, "region #0 is not memory?\n"); - err = -EINVAL; - goto err3; - } - - if (!(pci_resource_flags(dev, 1) & IORESOURCE_MEM)) { - dev_err(&dev->dev, "region #1 is not memory?\n"); - err = -EINVAL; - goto err3; - } - - /* make our resources ready for sharing */ - - sm->io_res = &dev->resource[1]; - sm->mem_res = &dev->resource[0]; - - sm->regs_claim = request_mem_region(sm->io_res->start, - 0x100, "sm501"); - if (sm->regs_claim == NULL) { - dev_err(&dev->dev, "cannot claim registers\n"); - err= -EBUSY; - goto err3; - } - - sm->regs = pci_ioremap_bar(dev, 1); - - if (sm->regs == NULL) { - dev_err(&dev->dev, "cannot remap registers\n"); - err = -EIO; - goto err4; - } - - sm501_init_dev(sm); - return 0; - - err4: - release_resource(sm->regs_claim); - kfree(sm->regs_claim); - err3: - pci_disable_device(dev); - err2: - pci_set_drvdata(dev, NULL); - kfree(sm); - err1: - return err; -} - -static void sm501_remove_sub(struct sm501_devdata *sm, - struct sm501_device *smdev) -{ - list_del(&smdev->list); - platform_device_unregister(&smdev->pdev); -} - -static void sm501_dev_remove(struct sm501_devdata *sm) -{ - struct sm501_device *smdev, *tmp; - - list_for_each_entry_safe(smdev, tmp, &sm->devices, list) - sm501_remove_sub(sm, smdev); - - device_remove_file(sm->dev, &dev_attr_dbg_regs); - - sm501_gpio_remove(sm); -} - -static void __devexit sm501_pci_remove(struct pci_dev *dev) -{ - struct sm501_devdata *sm = pci_get_drvdata(dev); - - sm501_dev_remove(sm); - iounmap(sm->regs); - - release_resource(sm->regs_claim); - kfree(sm->regs_claim); - - pci_set_drvdata(dev, NULL); - pci_disable_device(dev); -} - -static int sm501_plat_remove(struct platform_device *dev) -{ - struct sm501_devdata *sm = platform_get_drvdata(dev); - - sm501_dev_remove(sm); - iounmap(sm->regs); - - release_resource(sm->regs_claim); - kfree(sm->regs_claim); - - return 0; -} - -static DEFINE_PCI_DEVICE_TABLE(sm501_pci_tbl) = { - { 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, sm501_pci_tbl); - -static struct pci_driver sm501_pci_driver = { - .name = "sm501", - .id_table = sm501_pci_tbl, - .probe = sm501_pci_probe, - .remove = __devexit_p(sm501_pci_remove), -}; - -MODULE_ALIAS("platform:sm501"); - -static struct of_device_id __devinitdata of_sm501_match_tbl[] = { - { .compatible = "smi,sm501", }, - { /* end */ } -}; - -static struct platform_driver sm501_plat_driver = { - .driver = { - .name = "sm501", - .owner = THIS_MODULE, - .of_match_table = of_sm501_match_tbl, - }, - .probe = sm501_plat_probe, - .remove = sm501_plat_remove, - .suspend = sm501_plat_suspend, - .resume = sm501_plat_resume, -}; - -static int __init sm501_base_init(void) -{ - platform_driver_register(&sm501_plat_driver); - return pci_register_driver(&sm501_pci_driver); -} - -static void __exit sm501_base_exit(void) -{ - platform_driver_unregister(&sm501_plat_driver); - pci_unregister_driver(&sm501_pci_driver); -} - -module_init(sm501_base_init); -module_exit(sm501_base_exit); - -MODULE_DESCRIPTION("SM501 Core Driver"); -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, Vincent Sanders"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/stmpe-i2c.c b/ANDROID_3.4.5/drivers/mfd/stmpe-i2c.c deleted file mode 100644 index 373f423b..00000000 --- a/ANDROID_3.4.5/drivers/mfd/stmpe-i2c.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ST Microelectronics MFD: stmpe's i2c client specific driver - * - * Copyright (C) ST-Ericsson SA 2010 - * Copyright (C) ST Microelectronics SA 2011 - * - * License Terms: GNU General Public License, version 2 - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics - */ - -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/types.h> -#include "stmpe.h" - -static int i2c_reg_read(struct stmpe *stmpe, u8 reg) -{ - struct i2c_client *i2c = stmpe->client; - - return i2c_smbus_read_byte_data(i2c, reg); -} - -static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val) -{ - struct i2c_client *i2c = stmpe->client; - - return i2c_smbus_write_byte_data(i2c, reg, val); -} - -static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) -{ - struct i2c_client *i2c = stmpe->client; - - return i2c_smbus_read_i2c_block_data(i2c, reg, length, values); -} - -static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length, - const u8 *values) -{ - struct i2c_client *i2c = stmpe->client; - - return i2c_smbus_write_i2c_block_data(i2c, reg, length, values); -} - -static struct stmpe_client_info i2c_ci = { - .read_byte = i2c_reg_read, - .write_byte = i2c_reg_write, - .read_block = i2c_block_read, - .write_block = i2c_block_write, -}; - -static int __devinit -stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) -{ - i2c_ci.data = (void *)id; - i2c_ci.irq = i2c->irq; - i2c_ci.client = i2c; - i2c_ci.dev = &i2c->dev; - - return stmpe_probe(&i2c_ci, id->driver_data); -} - -static int __devexit stmpe_i2c_remove(struct i2c_client *i2c) -{ - struct stmpe *stmpe = dev_get_drvdata(&i2c->dev); - - return stmpe_remove(stmpe); -} - -static const struct i2c_device_id stmpe_i2c_id[] = { - { "stmpe610", STMPE610 }, - { "stmpe801", STMPE801 }, - { "stmpe811", STMPE811 }, - { "stmpe1601", STMPE1601 }, - { "stmpe2401", STMPE2401 }, - { "stmpe2403", STMPE2403 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, stmpe_id); - -static struct i2c_driver stmpe_i2c_driver = { - .driver.name = "stmpe-i2c", - .driver.owner = THIS_MODULE, -#ifdef CONFIG_PM - .driver.pm = &stmpe_dev_pm_ops, -#endif - .probe = stmpe_i2c_probe, - .remove = __devexit_p(stmpe_i2c_remove), - .id_table = stmpe_i2c_id, -}; - -static int __init stmpe_init(void) -{ - return i2c_add_driver(&stmpe_i2c_driver); -} -subsys_initcall(stmpe_init); - -static void __exit stmpe_exit(void) -{ - i2c_del_driver(&stmpe_i2c_driver); -} -module_exit(stmpe_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); -MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); diff --git a/ANDROID_3.4.5/drivers/mfd/stmpe-spi.c b/ANDROID_3.4.5/drivers/mfd/stmpe-spi.c deleted file mode 100644 index b58c43c7..00000000 --- a/ANDROID_3.4.5/drivers/mfd/stmpe-spi.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * ST Microelectronics MFD: stmpe's spi client specific driver - * - * Copyright (C) ST Microelectronics SA 2011 - * - * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics - */ - -#include <linux/spi/spi.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/types.h> -#include "stmpe.h" - -#define READ_CMD (1 << 7) - -static int spi_reg_read(struct stmpe *stmpe, u8 reg) -{ - struct spi_device *spi = stmpe->client; - int status = spi_w8r16(spi, reg | READ_CMD); - - return (status < 0) ? status : status >> 8; -} - -static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val) -{ - struct spi_device *spi = stmpe->client; - u16 cmd = (val << 8) | reg; - - return spi_write(spi, (const u8 *)&cmd, 2); -} - -static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) -{ - int ret, i; - - for (i = 0; i < length; i++) { - ret = spi_reg_read(stmpe, reg + i); - if (ret < 0) - return ret; - *(values + i) = ret; - } - - return 0; -} - -static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length, - const u8 *values) -{ - int ret = 0, i; - - for (i = length; i > 0; i--, reg++) { - ret = spi_reg_write(stmpe, reg, *(values + i - 1)); - if (ret < 0) - return ret; - } - - return ret; -} - -static void spi_init(struct stmpe *stmpe) -{ - struct spi_device *spi = stmpe->client; - - spi->bits_per_word = 8; - - /* This register is only present for stmpe811 */ - if (stmpe->variant->id_val == 0x0811) - spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode); - - if (spi_setup(spi) < 0) - dev_dbg(&spi->dev, "spi_setup failed\n"); -} - -static struct stmpe_client_info spi_ci = { - .read_byte = spi_reg_read, - .write_byte = spi_reg_write, - .read_block = spi_block_read, - .write_block = spi_block_write, - .init = spi_init, -}; - -static int __devinit -stmpe_spi_probe(struct spi_device *spi) -{ - const struct spi_device_id *id = spi_get_device_id(spi); - - /* don't exceed max specified rate - 1MHz - Limitation of STMPE */ - if (spi->max_speed_hz > 1000000) { - dev_dbg(&spi->dev, "f(sample) %d KHz?\n", - (spi->max_speed_hz/1000)); - return -EINVAL; - } - - spi_ci.irq = spi->irq; - spi_ci.client = spi; - spi_ci.dev = &spi->dev; - - return stmpe_probe(&spi_ci, id->driver_data); -} - -static int __devexit stmpe_spi_remove(struct spi_device *spi) -{ - struct stmpe *stmpe = dev_get_drvdata(&spi->dev); - - return stmpe_remove(stmpe); -} - -static const struct spi_device_id stmpe_spi_id[] = { - { "stmpe610", STMPE610 }, - { "stmpe801", STMPE801 }, - { "stmpe811", STMPE811 }, - { "stmpe1601", STMPE1601 }, - { "stmpe2401", STMPE2401 }, - { "stmpe2403", STMPE2403 }, - { } -}; -MODULE_DEVICE_TABLE(spi, stmpe_id); - -static struct spi_driver stmpe_spi_driver = { - .driver = { - .name = "stmpe-spi", - .bus = &spi_bus_type, - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &stmpe_dev_pm_ops, -#endif - }, - .probe = stmpe_spi_probe, - .remove = __devexit_p(stmpe_spi_remove), - .id_table = stmpe_spi_id, -}; - -static int __init stmpe_init(void) -{ - return spi_register_driver(&stmpe_spi_driver); -} -subsys_initcall(stmpe_init); - -static void __exit stmpe_exit(void) -{ - spi_unregister_driver(&stmpe_spi_driver); -} -module_exit(stmpe_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); diff --git a/ANDROID_3.4.5/drivers/mfd/stmpe.c b/ANDROID_3.4.5/drivers/mfd/stmpe.c deleted file mode 100644 index 2dd8d49c..00000000 --- a/ANDROID_3.4.5/drivers/mfd/stmpe.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * ST Microelectronics MFD: stmpe's driver - * - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License, version 2 - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - */ - -#include <linux/gpio.h> -#include <linux/export.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/pm.h> -#include <linux/slab.h> -#include <linux/mfd/core.h> -#include "stmpe.h" - -static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) -{ - return stmpe->variant->enable(stmpe, blocks, true); -} - -static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks) -{ - return stmpe->variant->enable(stmpe, blocks, false); -} - -static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) -{ - int ret; - - ret = stmpe->ci->read_byte(stmpe, reg); - if (ret < 0) - dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); - - dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); - - return ret; -} - -static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) -{ - int ret; - - dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); - - ret = stmpe->ci->write_byte(stmpe, reg, val); - if (ret < 0) - dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); - - return ret; -} - -static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) -{ - int ret; - - ret = __stmpe_reg_read(stmpe, reg); - if (ret < 0) - return ret; - - ret &= ~mask; - ret |= val; - - return __stmpe_reg_write(stmpe, reg, ret); -} - -static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, - u8 *values) -{ - int ret; - - ret = stmpe->ci->read_block(stmpe, reg, length, values); - if (ret < 0) - dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); - - dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); - stmpe_dump_bytes("stmpe rd: ", values, length); - - return ret; -} - -static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, - const u8 *values) -{ - int ret; - - dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); - stmpe_dump_bytes("stmpe wr: ", values, length); - - ret = stmpe->ci->write_block(stmpe, reg, length, values); - if (ret < 0) - dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); - - return ret; -} - -/** - * stmpe_enable - enable blocks on an STMPE device - * @stmpe: Device to work on - * @blocks: Mask of blocks (enum stmpe_block values) to enable - */ -int stmpe_enable(struct stmpe *stmpe, unsigned int blocks) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_enable(stmpe, blocks); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_enable); - -/** - * stmpe_disable - disable blocks on an STMPE device - * @stmpe: Device to work on - * @blocks: Mask of blocks (enum stmpe_block values) to enable - */ -int stmpe_disable(struct stmpe *stmpe, unsigned int blocks) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_disable(stmpe, blocks); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_disable); - -/** - * stmpe_reg_read() - read a single STMPE register - * @stmpe: Device to read from - * @reg: Register to read - */ -int stmpe_reg_read(struct stmpe *stmpe, u8 reg) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_reg_read(stmpe, reg); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_reg_read); - -/** - * stmpe_reg_write() - write a single STMPE register - * @stmpe: Device to write to - * @reg: Register to write - * @val: Value to write - */ -int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_reg_write(stmpe, reg, val); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_reg_write); - -/** - * stmpe_set_bits() - set the value of a bitfield in a STMPE register - * @stmpe: Device to write to - * @reg: Register to write - * @mask: Mask of bits to set - * @val: Value to set - */ -int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_set_bits(stmpe, reg, mask, val); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_set_bits); - -/** - * stmpe_block_read() - read multiple STMPE registers - * @stmpe: Device to read from - * @reg: First register - * @length: Number of registers - * @values: Buffer to write to - */ -int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_block_read(stmpe, reg, length, values); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_block_read); - -/** - * stmpe_block_write() - write multiple STMPE registers - * @stmpe: Device to write to - * @reg: First register - * @length: Number of registers - * @values: Values to write - */ -int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, - const u8 *values) -{ - int ret; - - mutex_lock(&stmpe->lock); - ret = __stmpe_block_write(stmpe, reg, length, values); - mutex_unlock(&stmpe->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_block_write); - -/** - * stmpe_set_altfunc()- set the alternate function for STMPE pins - * @stmpe: Device to configure - * @pins: Bitmask of pins to affect - * @block: block to enable alternate functions for - * - * @pins is assumed to have a bit set for each of the bits whose alternate - * function is to be changed, numbered according to the GPIOXY numbers. - * - * If the GPIO module is not enabled, this function automatically enables it in - * order to perform the change. - */ -int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) -{ - struct stmpe_variant_info *variant = stmpe->variant; - u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; - int af_bits = variant->af_bits; - int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); - int mask = (1 << af_bits) - 1; - u8 regs[numregs]; - int af, afperreg, ret; - - if (!variant->get_altfunc) - return 0; - - afperreg = 8 / af_bits; - mutex_lock(&stmpe->lock); - - ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); - if (ret < 0) - goto out; - - ret = __stmpe_block_read(stmpe, regaddr, numregs, regs); - if (ret < 0) - goto out; - - af = variant->get_altfunc(stmpe, block); - - while (pins) { - int pin = __ffs(pins); - int regoffset = numregs - (pin / afperreg) - 1; - int pos = (pin % afperreg) * (8 / afperreg); - - regs[regoffset] &= ~(mask << pos); - regs[regoffset] |= af << pos; - - pins &= ~(1 << pin); - } - - ret = __stmpe_block_write(stmpe, regaddr, numregs, regs); - -out: - mutex_unlock(&stmpe->lock); - return ret; -} -EXPORT_SYMBOL_GPL(stmpe_set_altfunc); - -/* - * GPIO (all variants) - */ - -static struct resource stmpe_gpio_resources[] = { - /* Start and end filled dynamically */ - { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell stmpe_gpio_cell = { - .name = "stmpe-gpio", - .resources = stmpe_gpio_resources, - .num_resources = ARRAY_SIZE(stmpe_gpio_resources), -}; - -static struct mfd_cell stmpe_gpio_cell_noirq = { - .name = "stmpe-gpio", - /* gpio cell resources consist of an irq only so no resources here */ -}; - -/* - * Keypad (1601, 2401, 2403) - */ - -static struct resource stmpe_keypad_resources[] = { - { - .name = "KEYPAD", - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, - { - .name = "KEYPAD_OVER", - .start = 1, - .end = 1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell stmpe_keypad_cell = { - .name = "stmpe-keypad", - .resources = stmpe_keypad_resources, - .num_resources = ARRAY_SIZE(stmpe_keypad_resources), -}; - -/* - * STMPE801 - */ -static const u8 stmpe801_regs[] = { - [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, - [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, - [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, - [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, - [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, - [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, - [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, - [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, - -}; - -static struct stmpe_variant_block stmpe801_blocks[] = { - { - .cell = &stmpe_gpio_cell, - .irq = 0, - .block = STMPE_BLOCK_GPIO, - }, -}; - -static struct stmpe_variant_block stmpe801_blocks_noirq[] = { - { - .cell = &stmpe_gpio_cell_noirq, - .block = STMPE_BLOCK_GPIO, - }, -}; - -static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, - bool enable) -{ - if (blocks & STMPE_BLOCK_GPIO) - return 0; - else - return -EINVAL; -} - -static struct stmpe_variant_info stmpe801 = { - .name = "stmpe801", - .id_val = STMPE801_ID, - .id_mask = 0xffff, - .num_gpios = 8, - .regs = stmpe801_regs, - .blocks = stmpe801_blocks, - .num_blocks = ARRAY_SIZE(stmpe801_blocks), - .num_irqs = STMPE801_NR_INTERNAL_IRQS, - .enable = stmpe801_enable, -}; - -static struct stmpe_variant_info stmpe801_noirq = { - .name = "stmpe801", - .id_val = STMPE801_ID, - .id_mask = 0xffff, - .num_gpios = 8, - .regs = stmpe801_regs, - .blocks = stmpe801_blocks_noirq, - .num_blocks = ARRAY_SIZE(stmpe801_blocks_noirq), - .enable = stmpe801_enable, -}; - -/* - * Touchscreen (STMPE811 or STMPE610) - */ - -static struct resource stmpe_ts_resources[] = { - { - .name = "TOUCH_DET", - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, - { - .name = "FIFO_TH", - .start = 1, - .end = 1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell stmpe_ts_cell = { - .name = "stmpe-ts", - .resources = stmpe_ts_resources, - .num_resources = ARRAY_SIZE(stmpe_ts_resources), -}; - -/* - * STMPE811 or STMPE610 - */ - -static const u8 stmpe811_regs[] = { - [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, - [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, - [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, - [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, - [STMPE_IDX_GPMR_LSB] = STMPE811_REG_GPIO_MP_STA, - [STMPE_IDX_GPSR_LSB] = STMPE811_REG_GPIO_SET_PIN, - [STMPE_IDX_GPCR_LSB] = STMPE811_REG_GPIO_CLR_PIN, - [STMPE_IDX_GPDR_LSB] = STMPE811_REG_GPIO_DIR, - [STMPE_IDX_GPRER_LSB] = STMPE811_REG_GPIO_RE, - [STMPE_IDX_GPFER_LSB] = STMPE811_REG_GPIO_FE, - [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, - [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, - [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, - [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, -}; - -static struct stmpe_variant_block stmpe811_blocks[] = { - { - .cell = &stmpe_gpio_cell, - .irq = STMPE811_IRQ_GPIOC, - .block = STMPE_BLOCK_GPIO, - }, - { - .cell = &stmpe_ts_cell, - .irq = STMPE811_IRQ_TOUCH_DET, - .block = STMPE_BLOCK_TOUCHSCREEN, - }, -}; - -static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, - bool enable) -{ - unsigned int mask = 0; - - if (blocks & STMPE_BLOCK_GPIO) - mask |= STMPE811_SYS_CTRL2_GPIO_OFF; - - if (blocks & STMPE_BLOCK_ADC) - mask |= STMPE811_SYS_CTRL2_ADC_OFF; - - if (blocks & STMPE_BLOCK_TOUCHSCREEN) - mask |= STMPE811_SYS_CTRL2_TSC_OFF; - - return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask, - enable ? 0 : mask); -} - -static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) -{ - /* 0 for touchscreen, 1 for GPIO */ - return block != STMPE_BLOCK_TOUCHSCREEN; -} - -static struct stmpe_variant_info stmpe811 = { - .name = "stmpe811", - .id_val = 0x0811, - .id_mask = 0xffff, - .num_gpios = 8, - .af_bits = 1, - .regs = stmpe811_regs, - .blocks = stmpe811_blocks, - .num_blocks = ARRAY_SIZE(stmpe811_blocks), - .num_irqs = STMPE811_NR_INTERNAL_IRQS, - .enable = stmpe811_enable, - .get_altfunc = stmpe811_get_altfunc, -}; - -/* Similar to 811, except number of gpios */ -static struct stmpe_variant_info stmpe610 = { - .name = "stmpe610", - .id_val = 0x0811, - .id_mask = 0xffff, - .num_gpios = 6, - .af_bits = 1, - .regs = stmpe811_regs, - .blocks = stmpe811_blocks, - .num_blocks = ARRAY_SIZE(stmpe811_blocks), - .num_irqs = STMPE811_NR_INTERNAL_IRQS, - .enable = stmpe811_enable, - .get_altfunc = stmpe811_get_altfunc, -}; - -/* - * STMPE1601 - */ - -static const u8 stmpe1601_regs[] = { - [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, - [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, - [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, - [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, - [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, - [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, - [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, - [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, - [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, - [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, - [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, - [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, - [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, - [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, -}; - -static struct stmpe_variant_block stmpe1601_blocks[] = { - { - .cell = &stmpe_gpio_cell, - .irq = STMPE24XX_IRQ_GPIOC, - .block = STMPE_BLOCK_GPIO, - }, - { - .cell = &stmpe_keypad_cell, - .irq = STMPE24XX_IRQ_KEYPAD, - .block = STMPE_BLOCK_KEYPAD, - }, -}; - -/* supported autosleep timeout delay (in msecs) */ -static const int stmpe_autosleep_delay[] = { - 4, 16, 32, 64, 128, 256, 512, 1024, -}; - -static int stmpe_round_timeout(int timeout) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) { - if (stmpe_autosleep_delay[i] >= timeout) - return i; - } - - /* - * requests for delays longer than supported should not return the - * longest supported delay - */ - return -EINVAL; -} - -static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout) -{ - int ret; - - if (!stmpe->variant->enable_autosleep) - return -ENOSYS; - - mutex_lock(&stmpe->lock); - ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout); - mutex_unlock(&stmpe->lock); - - return ret; -} - -/* - * Both stmpe 1601/2403 support same layout for autosleep - */ -static int stmpe1601_autosleep(struct stmpe *stmpe, - int autosleep_timeout) -{ - int ret, timeout; - - /* choose the best available timeout */ - timeout = stmpe_round_timeout(autosleep_timeout); - if (timeout < 0) { - dev_err(stmpe->dev, "invalid timeout\n"); - return timeout; - } - - ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, - STMPE1601_AUTOSLEEP_TIMEOUT_MASK, - timeout); - if (ret < 0) - return ret; - - return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, - STPME1601_AUTOSLEEP_ENABLE, - STPME1601_AUTOSLEEP_ENABLE); -} - -static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, - bool enable) -{ - unsigned int mask = 0; - - if (blocks & STMPE_BLOCK_GPIO) - mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; - - if (blocks & STMPE_BLOCK_KEYPAD) - mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; - - return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, - enable ? mask : 0); -} - -static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) -{ - switch (block) { - case STMPE_BLOCK_PWM: - return 2; - - case STMPE_BLOCK_KEYPAD: - return 1; - - case STMPE_BLOCK_GPIO: - default: - return 0; - } -} - -static struct stmpe_variant_info stmpe1601 = { - .name = "stmpe1601", - .id_val = 0x0210, - .id_mask = 0xfff0, /* at least 0x0210 and 0x0212 */ - .num_gpios = 16, - .af_bits = 2, - .regs = stmpe1601_regs, - .blocks = stmpe1601_blocks, - .num_blocks = ARRAY_SIZE(stmpe1601_blocks), - .num_irqs = STMPE1601_NR_INTERNAL_IRQS, - .enable = stmpe1601_enable, - .get_altfunc = stmpe1601_get_altfunc, - .enable_autosleep = stmpe1601_autosleep, -}; - -/* - * STMPE24XX - */ - -static const u8 stmpe24xx_regs[] = { - [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, - [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, - [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, - [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, - [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, - [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, - [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, - [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, - [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, - [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, - [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, - [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, - [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, - [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, -}; - -static struct stmpe_variant_block stmpe24xx_blocks[] = { - { - .cell = &stmpe_gpio_cell, - .irq = STMPE24XX_IRQ_GPIOC, - .block = STMPE_BLOCK_GPIO, - }, - { - .cell = &stmpe_keypad_cell, - .irq = STMPE24XX_IRQ_KEYPAD, - .block = STMPE_BLOCK_KEYPAD, - }, -}; - -static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, - bool enable) -{ - unsigned int mask = 0; - - if (blocks & STMPE_BLOCK_GPIO) - mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO; - - if (blocks & STMPE_BLOCK_KEYPAD) - mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; - - return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask, - enable ? mask : 0); -} - -static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) -{ - switch (block) { - case STMPE_BLOCK_ROTATOR: - return 2; - - case STMPE_BLOCK_KEYPAD: - return 1; - - case STMPE_BLOCK_GPIO: - default: - return 0; - } -} - -static struct stmpe_variant_info stmpe2401 = { - .name = "stmpe2401", - .id_val = 0x0101, - .id_mask = 0xffff, - .num_gpios = 24, - .af_bits = 2, - .regs = stmpe24xx_regs, - .blocks = stmpe24xx_blocks, - .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), - .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, - .enable = stmpe24xx_enable, - .get_altfunc = stmpe24xx_get_altfunc, -}; - -static struct stmpe_variant_info stmpe2403 = { - .name = "stmpe2403", - .id_val = 0x0120, - .id_mask = 0xffff, - .num_gpios = 24, - .af_bits = 2, - .regs = stmpe24xx_regs, - .blocks = stmpe24xx_blocks, - .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), - .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, - .enable = stmpe24xx_enable, - .get_altfunc = stmpe24xx_get_altfunc, - .enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */ -}; - -static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { - [STMPE610] = &stmpe610, - [STMPE801] = &stmpe801, - [STMPE811] = &stmpe811, - [STMPE1601] = &stmpe1601, - [STMPE2401] = &stmpe2401, - [STMPE2403] = &stmpe2403, -}; - -/* - * These devices can be connected in a 'no-irq' configuration - the irq pin - * is not used and the device cannot interrupt the CPU. Here we only list - * devices which support this configuration - the driver will fail probing - * for any devices not listed here which are configured in this way. - */ -static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = { - [STMPE801] = &stmpe801_noirq, -}; - -static irqreturn_t stmpe_irq(int irq, void *data) -{ - struct stmpe *stmpe = data; - struct stmpe_variant_info *variant = stmpe->variant; - int num = DIV_ROUND_UP(variant->num_irqs, 8); - u8 israddr = stmpe->regs[STMPE_IDX_ISR_MSB]; - u8 isr[num]; - int ret; - int i; - - if (variant->id_val == STMPE801_ID) { - handle_nested_irq(stmpe->irq_base); - return IRQ_HANDLED; - } - - ret = stmpe_block_read(stmpe, israddr, num, isr); - if (ret < 0) - return IRQ_NONE; - - for (i = 0; i < num; i++) { - int bank = num - i - 1; - u8 status = isr[i]; - u8 clear; - - status &= stmpe->ier[bank]; - if (!status) - continue; - - clear = status; - while (status) { - int bit = __ffs(status); - int line = bank * 8 + bit; - - handle_nested_irq(stmpe->irq_base + line); - status &= ~(1 << bit); - } - - stmpe_reg_write(stmpe, israddr + i, clear); - } - - return IRQ_HANDLED; -} - -static void stmpe_irq_lock(struct irq_data *data) -{ - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - - mutex_lock(&stmpe->irq_lock); -} - -static void stmpe_irq_sync_unlock(struct irq_data *data) -{ - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - struct stmpe_variant_info *variant = stmpe->variant; - int num = DIV_ROUND_UP(variant->num_irqs, 8); - int i; - - for (i = 0; i < num; i++) { - u8 new = stmpe->ier[i]; - u8 old = stmpe->oldier[i]; - - if (new == old) - continue; - - stmpe->oldier[i] = new; - stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new); - } - - mutex_unlock(&stmpe->irq_lock); -} - -static void stmpe_irq_mask(struct irq_data *data) -{ - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; - int regoffset = offset / 8; - int mask = 1 << (offset % 8); - - stmpe->ier[regoffset] &= ~mask; -} - -static void stmpe_irq_unmask(struct irq_data *data) -{ - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; - int regoffset = offset / 8; - int mask = 1 << (offset % 8); - - stmpe->ier[regoffset] |= mask; -} - -static struct irq_chip stmpe_irq_chip = { - .name = "stmpe", - .irq_bus_lock = stmpe_irq_lock, - .irq_bus_sync_unlock = stmpe_irq_sync_unlock, - .irq_mask = stmpe_irq_mask, - .irq_unmask = stmpe_irq_unmask, -}; - -static int __devinit stmpe_irq_init(struct stmpe *stmpe) -{ - struct irq_chip *chip = NULL; - int num_irqs = stmpe->variant->num_irqs; - int base = stmpe->irq_base; - int irq; - - if (stmpe->variant->id_val != STMPE801_ID) - chip = &stmpe_irq_chip; - - for (irq = base; irq < base + num_irqs; irq++) { - irq_set_chip_data(irq, stmpe); - irq_set_chip_and_handler(irq, chip, handle_edge_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - } - - return 0; -} - -static void stmpe_irq_remove(struct stmpe *stmpe) -{ - int num_irqs = stmpe->variant->num_irqs; - int base = stmpe->irq_base; - int irq; - - for (irq = base; irq < base + num_irqs; irq++) { -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); - } -} - -static int __devinit stmpe_chip_init(struct stmpe *stmpe) -{ - unsigned int irq_trigger = stmpe->pdata->irq_trigger; - int autosleep_timeout = stmpe->pdata->autosleep_timeout; - struct stmpe_variant_info *variant = stmpe->variant; - u8 icr = 0; - unsigned int id; - u8 data[2]; - int ret; - - ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID], - ARRAY_SIZE(data), data); - if (ret < 0) - return ret; - - id = (data[0] << 8) | data[1]; - if ((id & variant->id_mask) != variant->id_val) { - dev_err(stmpe->dev, "unknown chip id: %#x\n", id); - return -EINVAL; - } - - dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id); - - /* Disable all modules -- subdrivers should enable what they need. */ - ret = stmpe_disable(stmpe, ~0); - if (ret) - return ret; - - if (stmpe->irq >= 0) { - if (id == STMPE801_ID) - icr = STMPE801_REG_SYS_CTRL_INT_EN; - else - icr = STMPE_ICR_LSB_GIM; - - /* STMPE801 doesn't support Edge interrupts */ - if (id != STMPE801_ID) { - if (irq_trigger == IRQF_TRIGGER_FALLING || - irq_trigger == IRQF_TRIGGER_RISING) - icr |= STMPE_ICR_LSB_EDGE; - } - - if (irq_trigger == IRQF_TRIGGER_RISING || - irq_trigger == IRQF_TRIGGER_HIGH) { - if (id == STMPE801_ID) - icr |= STMPE801_REG_SYS_CTRL_INT_HI; - else - icr |= STMPE_ICR_LSB_HIGH; - } - - if (stmpe->pdata->irq_invert_polarity) { - if (id == STMPE801_ID) - icr ^= STMPE801_REG_SYS_CTRL_INT_HI; - else - icr ^= STMPE_ICR_LSB_HIGH; - } - } - - if (stmpe->pdata->autosleep) { - ret = stmpe_autosleep(stmpe, autosleep_timeout); - if (ret) - return ret; - } - - return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr); -} - -static int __devinit stmpe_add_device(struct stmpe *stmpe, - struct mfd_cell *cell, int irq) -{ - return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, - NULL, stmpe->irq_base + irq); -} - -static int __devinit stmpe_devices_init(struct stmpe *stmpe) -{ - struct stmpe_variant_info *variant = stmpe->variant; - unsigned int platform_blocks = stmpe->pdata->blocks; - int ret = -EINVAL; - int i; - - for (i = 0; i < variant->num_blocks; i++) { - struct stmpe_variant_block *block = &variant->blocks[i]; - - if (!(platform_blocks & block->block)) - continue; - - platform_blocks &= ~block->block; - ret = stmpe_add_device(stmpe, block->cell, block->irq); - if (ret) - return ret; - } - - if (platform_blocks) - dev_warn(stmpe->dev, - "platform wants blocks (%#x) not present on variant", - platform_blocks); - - return ret; -} - -/* Called from client specific probe routines */ -int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) -{ - struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); - struct stmpe *stmpe; - int ret; - - if (!pdata) - return -EINVAL; - - stmpe = kzalloc(sizeof(struct stmpe), GFP_KERNEL); - if (!stmpe) - return -ENOMEM; - - mutex_init(&stmpe->irq_lock); - mutex_init(&stmpe->lock); - - stmpe->dev = ci->dev; - stmpe->client = ci->client; - stmpe->pdata = pdata; - stmpe->irq_base = pdata->irq_base; - stmpe->ci = ci; - stmpe->partnum = partnum; - stmpe->variant = stmpe_variant_info[partnum]; - stmpe->regs = stmpe->variant->regs; - stmpe->num_gpios = stmpe->variant->num_gpios; - dev_set_drvdata(stmpe->dev, stmpe); - - if (ci->init) - ci->init(stmpe); - - if (pdata->irq_over_gpio) { - ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe"); - if (ret) { - dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", - ret); - goto out_free; - } - - stmpe->irq = gpio_to_irq(pdata->irq_gpio); - } else { - stmpe->irq = ci->irq; - } - - if (stmpe->irq < 0) { - /* use alternate variant info for no-irq mode, if supported */ - dev_info(stmpe->dev, - "%s configured in no-irq mode by platform data\n", - stmpe->variant->name); - if (!stmpe_noirq_variant_info[stmpe->partnum]) { - dev_err(stmpe->dev, - "%s does not support no-irq mode!\n", - stmpe->variant->name); - ret = -ENODEV; - goto free_gpio; - } - stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum]; - } - - ret = stmpe_chip_init(stmpe); - if (ret) - goto free_gpio; - - if (stmpe->irq >= 0) { - ret = stmpe_irq_init(stmpe); - if (ret) - goto free_gpio; - - ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, - pdata->irq_trigger | IRQF_ONESHOT, - "stmpe", stmpe); - if (ret) { - dev_err(stmpe->dev, "failed to request IRQ: %d\n", - ret); - goto out_removeirq; - } - } - - ret = stmpe_devices_init(stmpe); - if (ret) { - dev_err(stmpe->dev, "failed to add children\n"); - goto out_removedevs; - } - - return 0; - -out_removedevs: - mfd_remove_devices(stmpe->dev); - if (stmpe->irq >= 0) - free_irq(stmpe->irq, stmpe); -out_removeirq: - if (stmpe->irq >= 0) - stmpe_irq_remove(stmpe); -free_gpio: - if (pdata->irq_over_gpio) - gpio_free(pdata->irq_gpio); -out_free: - kfree(stmpe); - return ret; -} - -int stmpe_remove(struct stmpe *stmpe) -{ - mfd_remove_devices(stmpe->dev); - - if (stmpe->irq >= 0) { - free_irq(stmpe->irq, stmpe); - stmpe_irq_remove(stmpe); - } - - if (stmpe->pdata->irq_over_gpio) - gpio_free(stmpe->pdata->irq_gpio); - - kfree(stmpe); - - return 0; -} - -#ifdef CONFIG_PM -static int stmpe_suspend(struct device *dev) -{ - struct stmpe *stmpe = dev_get_drvdata(dev); - - if (stmpe->irq >= 0 && device_may_wakeup(dev)) - enable_irq_wake(stmpe->irq); - - return 0; -} - -static int stmpe_resume(struct device *dev) -{ - struct stmpe *stmpe = dev_get_drvdata(dev); - - if (stmpe->irq >= 0 && device_may_wakeup(dev)) - disable_irq_wake(stmpe->irq); - - return 0; -} - -const struct dev_pm_ops stmpe_dev_pm_ops = { - .suspend = stmpe_suspend, - .resume = stmpe_resume, -}; -#endif diff --git a/ANDROID_3.4.5/drivers/mfd/stmpe.h b/ANDROID_3.4.5/drivers/mfd/stmpe.h deleted file mode 100644 index 7b8e13f5..00000000 --- a/ANDROID_3.4.5/drivers/mfd/stmpe.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License, version 2 - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - */ - -#ifndef __STMPE_H -#define __STMPE_H - -#include <linux/device.h> -#include <linux/mfd/core.h> -#include <linux/mfd/stmpe.h> -#include <linux/printk.h> -#include <linux/types.h> - -extern const struct dev_pm_ops stmpe_dev_pm_ops; - -#ifdef STMPE_DUMP_BYTES -static inline void stmpe_dump_bytes(const char *str, const void *buf, - size_t len) -{ - print_hex_dump_bytes(str, DUMP_PREFIX_OFFSET, buf, len); -} -#else -static inline void stmpe_dump_bytes(const char *str, const void *buf, - size_t len) -{ -} -#endif - -/** - * struct stmpe_variant_block - information about block - * @cell: base mfd cell - * @irq: interrupt number to be added to each IORESOURCE_IRQ - * in the cell - * @block: block id; used for identification with platform data and for - * enable and altfunc callbacks - */ -struct stmpe_variant_block { - struct mfd_cell *cell; - int irq; - enum stmpe_block block; -}; - -/** - * struct stmpe_variant_info - variant-specific information - * @name: part name - * @id_val: content of CHIPID register - * @id_mask: bits valid in CHIPID register for comparison with id_val - * @num_gpios: number of GPIOS - * @af_bits: number of bits used to specify the alternate function - * @regs: variant specific registers. - * @blocks: list of blocks present on this device - * @num_blocks: number of blocks present on this device - * @num_irqs: number of internal IRQs available on this device - * @enable: callback to enable the specified blocks. - * Called with the I/O lock held. - * @get_altfunc: callback to get the alternate function number for the - * specific block - * @enable_autosleep: callback to configure autosleep with specified timeout - */ -struct stmpe_variant_info { - const char *name; - u16 id_val; - u16 id_mask; - int num_gpios; - int af_bits; - const u8 *regs; - struct stmpe_variant_block *blocks; - int num_blocks; - int num_irqs; - int (*enable)(struct stmpe *stmpe, unsigned int blocks, bool enable); - int (*get_altfunc)(struct stmpe *stmpe, enum stmpe_block block); - int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); -}; - -/** - * struct stmpe_client_info - i2c or spi specific routines/info - * @data: client specific data - * @read_byte: read single byte - * @write_byte: write single byte - * @read_block: read block or multiple bytes - * @write_block: write block or multiple bytes - * @init: client init routine, called during probe - */ -struct stmpe_client_info { - void *data; - int irq; - void *client; - struct device *dev; - int (*read_byte)(struct stmpe *stmpe, u8 reg); - int (*write_byte)(struct stmpe *stmpe, u8 reg, u8 val); - int (*read_block)(struct stmpe *stmpe, u8 reg, u8 len, u8 *values); - int (*write_block)(struct stmpe *stmpe, u8 reg, u8 len, - const u8 *values); - void (*init)(struct stmpe *stmpe); -}; - -int stmpe_probe(struct stmpe_client_info *ci, int partnum); -int stmpe_remove(struct stmpe *stmpe); - -#define STMPE_ICR_LSB_HIGH (1 << 2) -#define STMPE_ICR_LSB_EDGE (1 << 1) -#define STMPE_ICR_LSB_GIM (1 << 0) - -/* - * STMPE801 - */ -#define STMPE801_ID 0x0108 -#define STMPE801_NR_INTERNAL_IRQS 1 - -#define STMPE801_REG_CHIP_ID 0x00 -#define STMPE801_REG_VERSION_ID 0x02 -#define STMPE801_REG_SYS_CTRL 0x04 -#define STMPE801_REG_GPIO_INT_EN 0x08 -#define STMPE801_REG_GPIO_INT_STA 0x09 -#define STMPE801_REG_GPIO_MP_STA 0x10 -#define STMPE801_REG_GPIO_SET_PIN 0x11 -#define STMPE801_REG_GPIO_DIR 0x12 - -#define STMPE801_REG_SYS_CTRL_RESET (1 << 7) -#define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) -#define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) - -/* - * STMPE811 - */ - -#define STMPE811_IRQ_TOUCH_DET 0 -#define STMPE811_IRQ_FIFO_TH 1 -#define STMPE811_IRQ_FIFO_OFLOW 2 -#define STMPE811_IRQ_FIFO_FULL 3 -#define STMPE811_IRQ_FIFO_EMPTY 4 -#define STMPE811_IRQ_TEMP_SENS 5 -#define STMPE811_IRQ_ADC 6 -#define STMPE811_IRQ_GPIOC 7 -#define STMPE811_NR_INTERNAL_IRQS 8 - -#define STMPE811_REG_CHIP_ID 0x00 -#define STMPE811_REG_SYS_CTRL2 0x04 -#define STMPE811_REG_SPI_CFG 0x08 -#define STMPE811_REG_INT_CTRL 0x09 -#define STMPE811_REG_INT_EN 0x0A -#define STMPE811_REG_INT_STA 0x0B -#define STMPE811_REG_GPIO_INT_EN 0x0C -#define STMPE811_REG_GPIO_INT_STA 0x0D -#define STMPE811_REG_GPIO_SET_PIN 0x10 -#define STMPE811_REG_GPIO_CLR_PIN 0x11 -#define STMPE811_REG_GPIO_MP_STA 0x12 -#define STMPE811_REG_GPIO_DIR 0x13 -#define STMPE811_REG_GPIO_ED 0x14 -#define STMPE811_REG_GPIO_RE 0x15 -#define STMPE811_REG_GPIO_FE 0x16 -#define STMPE811_REG_GPIO_AF 0x17 - -#define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0) -#define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1) -#define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2) -#define STMPE811_SYS_CTRL2_TS_OFF (1 << 3) - -/* - * STMPE1601 - */ - -#define STMPE1601_IRQ_GPIOC 8 -#define STMPE1601_IRQ_PWM3 7 -#define STMPE1601_IRQ_PWM2 6 -#define STMPE1601_IRQ_PWM1 5 -#define STMPE1601_IRQ_PWM0 4 -#define STMPE1601_IRQ_KEYPAD_OVER 2 -#define STMPE1601_IRQ_KEYPAD 1 -#define STMPE1601_IRQ_WAKEUP 0 -#define STMPE1601_NR_INTERNAL_IRQS 9 - -#define STMPE1601_REG_SYS_CTRL 0x02 -#define STMPE1601_REG_SYS_CTRL2 0x03 -#define STMPE1601_REG_ICR_LSB 0x11 -#define STMPE1601_REG_IER_LSB 0x13 -#define STMPE1601_REG_ISR_MSB 0x14 -#define STMPE1601_REG_CHIP_ID 0x80 -#define STMPE1601_REG_INT_EN_GPIO_MASK_LSB 0x17 -#define STMPE1601_REG_INT_STA_GPIO_MSB 0x18 -#define STMPE1601_REG_GPIO_MP_LSB 0x87 -#define STMPE1601_REG_GPIO_SET_LSB 0x83 -#define STMPE1601_REG_GPIO_CLR_LSB 0x85 -#define STMPE1601_REG_GPIO_SET_DIR_LSB 0x89 -#define STMPE1601_REG_GPIO_ED_MSB 0x8A -#define STMPE1601_REG_GPIO_RE_LSB 0x8D -#define STMPE1601_REG_GPIO_FE_LSB 0x8F -#define STMPE1601_REG_GPIO_AF_U_MSB 0x92 - -#define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) -#define STMPE1601_SYS_CTRL_ENABLE_KPC (1 << 1) -#define STMPE1601_SYSCON_ENABLE_SPWM (1 << 0) - -/* The 1601/2403 share the same masks */ -#define STMPE1601_AUTOSLEEP_TIMEOUT_MASK (0x7) -#define STPME1601_AUTOSLEEP_ENABLE (1 << 3) - -/* - * STMPE24xx - */ - -#define STMPE24XX_IRQ_GPIOC 8 -#define STMPE24XX_IRQ_PWM2 7 -#define STMPE24XX_IRQ_PWM1 6 -#define STMPE24XX_IRQ_PWM0 5 -#define STMPE24XX_IRQ_ROT_OVER 4 -#define STMPE24XX_IRQ_ROT 3 -#define STMPE24XX_IRQ_KEYPAD_OVER 2 -#define STMPE24XX_IRQ_KEYPAD 1 -#define STMPE24XX_IRQ_WAKEUP 0 -#define STMPE24XX_NR_INTERNAL_IRQS 9 - -#define STMPE24XX_REG_SYS_CTRL 0x02 -#define STMPE24XX_REG_ICR_LSB 0x11 -#define STMPE24XX_REG_IER_LSB 0x13 -#define STMPE24XX_REG_ISR_MSB 0x14 -#define STMPE24XX_REG_CHIP_ID 0x80 -#define STMPE24XX_REG_IEGPIOR_LSB 0x18 -#define STMPE24XX_REG_ISGPIOR_MSB 0x19 -#define STMPE24XX_REG_GPMR_LSB 0xA5 -#define STMPE24XX_REG_GPSR_LSB 0x85 -#define STMPE24XX_REG_GPCR_LSB 0x88 -#define STMPE24XX_REG_GPDR_LSB 0x8B -#define STMPE24XX_REG_GPEDR_MSB 0x8C -#define STMPE24XX_REG_GPRER_LSB 0x91 -#define STMPE24XX_REG_GPFER_LSB 0x94 -#define STMPE24XX_REG_GPAFR_U_MSB 0x9B - -#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) -#define STMPE24XX_SYSCON_ENABLE_PWM (1 << 2) -#define STMPE24XX_SYS_CTRL_ENABLE_KPC (1 << 1) -#define STMPE24XX_SYSCON_ENABLE_ROT (1 << 0) - -#endif diff --git a/ANDROID_3.4.5/drivers/mfd/t7l66xb.c b/ANDROID_3.4.5/drivers/mfd/t7l66xb.c deleted file mode 100644 index 2d9e8799..00000000 --- a/ANDROID_3.4.5/drivers/mfd/t7l66xb.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * - * Toshiba T7L66XB core mfd support - * - * Copyright (c) 2005, 2007, 2008 Ian Molton - * Copyright (c) 2008 Dmitry Baryshkov - * - * 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. - * - * T7L66 features: - * - * Supported in this driver: - * SD/MMC - * SM/NAND flash controller - * - * As yet not supported - * GPIO interface (on NAND pins) - * Serial interface - * TFT 'interface converter' - * PCMCIA interface logic - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/irq.h> -#include <linux/clk.h> -#include <linux/platform_device.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tmio.h> -#include <linux/mfd/t7l66xb.h> - -enum { - T7L66XB_CELL_NAND, - T7L66XB_CELL_MMC, -}; - -static const struct resource t7l66xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_T7L66XB_MMC, - .end = IRQ_T7L66XB_MMC, - .flags = IORESOURCE_IRQ, - }, -}; - -#define SCR_REVID 0x08 /* b Revision ID */ -#define SCR_IMR 0x42 /* b Interrupt Mask */ -#define SCR_DEV_CTL 0xe0 /* b Device control */ -#define SCR_ISR 0xe1 /* b Interrupt Status */ -#define SCR_GPO_OC 0xf0 /* b GPO output control */ -#define SCR_GPO_OS 0xf1 /* b GPO output enable */ -#define SCR_GPI_S 0xf2 /* w GPI status */ -#define SCR_APDC 0xf8 /* b Active pullup down ctrl */ - -#define SCR_DEV_CTL_USB BIT(0) /* USB enable */ -#define SCR_DEV_CTL_MMC BIT(1) /* MMC enable */ - -/*--------------------------------------------------------------------------*/ - -struct t7l66xb { - void __iomem *scr; - /* Lock to protect registers requiring read/modify/write ops. */ - spinlock_t lock; - - struct resource rscr; - struct clk *clk48m; - struct clk *clk32k; - int irq; - int irq_base; -}; - -/*--------------------------------------------------------------------------*/ - -static int t7l66xb_mmc_enable(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned long flags; - u8 dev_ctl; - - clk_enable(t7l66xb->clk32k); - - spin_lock_irqsave(&t7l66xb->lock, flags); - - dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); - dev_ctl |= SCR_DEV_CTL_MMC; - tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); - - spin_unlock_irqrestore(&t7l66xb->lock, flags); - - tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, - t7l66xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int t7l66xb_mmc_disable(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned long flags; - u8 dev_ctl; - - spin_lock_irqsave(&t7l66xb->lock, flags); - - dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); - dev_ctl &= ~SCR_DEV_CTL_MMC; - tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); - - spin_unlock_irqrestore(&t7l66xb->lock, flags); - - clk_disable(t7l66xb->clk32k); - - return 0; -} - -static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - - tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state); -} - -static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - - tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state); -} - -/*--------------------------------------------------------------------------*/ - -static struct tmio_mmc_data t7166xb_mmc_data = { - .hclk = 24000000, - .set_pwr = t7l66xb_mmc_pwr, - .set_clk_div = t7l66xb_mmc_clk_div, -}; - -static const struct resource t7l66xb_nand_resources[] = { - { - .start = 0xc00, - .end = 0xc07, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0100, - .end = 0x01ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_T7L66XB_NAND, - .end = IRQ_T7L66XB_NAND, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell t7l66xb_cells[] = { - [T7L66XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = t7l66xb_mmc_enable, - .disable = t7l66xb_mmc_disable, - .platform_data = &t7166xb_mmc_data, - .pdata_size = sizeof(t7166xb_mmc_data), - .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), - .resources = t7l66xb_mmc_resources, - }, - [T7L66XB_CELL_NAND] = { - .name = "tmio-nand", - .num_resources = ARRAY_SIZE(t7l66xb_nand_resources), - .resources = t7l66xb_nand_resources, - }, -}; - -/*--------------------------------------------------------------------------*/ - -/* Handle the T7L66XB interrupt mux */ -static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) -{ - struct t7l66xb *t7l66xb = irq_get_handler_data(irq); - unsigned int isr; - unsigned int i, irq_base; - - irq_base = t7l66xb->irq_base; - - while ((isr = tmio_ioread8(t7l66xb->scr + SCR_ISR) & - ~tmio_ioread8(t7l66xb->scr + SCR_IMR))) - for (i = 0; i < T7L66XB_NR_IRQS; i++) - if (isr & (1 << i)) - generic_handle_irq(irq_base + i); -} - -static void t7l66xb_irq_mask(struct irq_data *data) -{ - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - spin_lock_irqsave(&t7l66xb->lock, flags); - imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr |= 1 << (data->irq - t7l66xb->irq_base); - tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); - spin_unlock_irqrestore(&t7l66xb->lock, flags); -} - -static void t7l66xb_irq_unmask(struct irq_data *data) -{ - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - spin_lock_irqsave(&t7l66xb->lock, flags); - imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - t7l66xb->irq_base)); - tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); - spin_unlock_irqrestore(&t7l66xb->lock, flags); -} - -static struct irq_chip t7l66xb_chip = { - .name = "t7l66xb", - .irq_ack = t7l66xb_irq_mask, - .irq_mask = t7l66xb_irq_mask, - .irq_unmask = t7l66xb_irq_unmask, -}; - -/*--------------------------------------------------------------------------*/ - -/* Install the IRQ handler */ -static void t7l66xb_attach_irq(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = t7l66xb->irq_base; - - for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq); - irq_set_chip_data(irq, t7l66xb); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -#endif - } - - irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_handler_data(t7l66xb->irq, t7l66xb); - irq_set_chained_handler(t7l66xb->irq, t7l66xb_irq); -} - -static void t7l66xb_detach_irq(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = t7l66xb->irq_base; - - irq_set_chained_handler(t7l66xb->irq, NULL); - irq_set_handler_data(t7l66xb->irq, NULL); - - for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); - } -} - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM -static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - struct t7l66xb_platform_data *pdata = dev->dev.platform_data; - - if (pdata && pdata->suspend) - pdata->suspend(dev); - clk_disable(t7l66xb->clk48m); - - return 0; -} - -static int t7l66xb_resume(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - struct t7l66xb_platform_data *pdata = dev->dev.platform_data; - - clk_enable(t7l66xb->clk48m); - if (pdata && pdata->resume) - pdata->resume(dev); - - tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, - t7l66xb_mmc_resources[0].start & 0xfffe); - - return 0; -} -#else -#define t7l66xb_suspend NULL -#define t7l66xb_resume NULL -#endif - -/*--------------------------------------------------------------------------*/ - -static int t7l66xb_probe(struct platform_device *dev) -{ - struct t7l66xb_platform_data *pdata = dev->dev.platform_data; - struct t7l66xb *t7l66xb; - struct resource *iomem, *rscr; - int ret; - - if (pdata == NULL) - return -EINVAL; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) - return -EINVAL; - - t7l66xb = kzalloc(sizeof *t7l66xb, GFP_KERNEL); - if (!t7l66xb) - return -ENOMEM; - - spin_lock_init(&t7l66xb->lock); - - platform_set_drvdata(dev, t7l66xb); - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - t7l66xb->irq = ret; - else - goto err_noirq; - - t7l66xb->irq_base = pdata->irq_base; - - t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K"); - if (IS_ERR(t7l66xb->clk32k)) { - ret = PTR_ERR(t7l66xb->clk32k); - goto err_clk32k_get; - } - - t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M"); - if (IS_ERR(t7l66xb->clk48m)) { - ret = PTR_ERR(t7l66xb->clk48m); - goto err_clk48m_get; - } - - rscr = &t7l66xb->rscr; - rscr->name = "t7l66xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_request_scr; - - t7l66xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!t7l66xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - clk_enable(t7l66xb->clk48m); - - if (pdata && pdata->enable) - pdata->enable(dev); - - /* Mask all interrupts */ - tmio_iowrite8(0xbf, t7l66xb->scr + SCR_IMR); - - printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n", - dev->name, tmio_ioread8(t7l66xb->scr + SCR_REVID), - (unsigned long)iomem->start, t7l66xb->irq); - - t7l66xb_attach_irq(dev); - - t7l66xb_cells[T7L66XB_CELL_NAND].platform_data = pdata->nand_data; - t7l66xb_cells[T7L66XB_CELL_NAND].pdata_size = sizeof(*pdata->nand_data); - - ret = mfd_add_devices(&dev->dev, dev->id, - t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), - iomem, t7l66xb->irq_base); - - if (!ret) - return 0; - - t7l66xb_detach_irq(dev); - iounmap(t7l66xb->scr); -err_ioremap: - release_resource(&t7l66xb->rscr); -err_request_scr: - clk_put(t7l66xb->clk48m); -err_clk48m_get: - clk_put(t7l66xb->clk32k); -err_clk32k_get: -err_noirq: - kfree(t7l66xb); - return ret; -} - -static int t7l66xb_remove(struct platform_device *dev) -{ - struct t7l66xb_platform_data *pdata = dev->dev.platform_data; - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - int ret; - - ret = pdata->disable(dev); - clk_disable(t7l66xb->clk48m); - clk_put(t7l66xb->clk48m); - clk_disable(t7l66xb->clk32k); - clk_put(t7l66xb->clk32k); - t7l66xb_detach_irq(dev); - iounmap(t7l66xb->scr); - release_resource(&t7l66xb->rscr); - mfd_remove_devices(&dev->dev); - platform_set_drvdata(dev, NULL); - kfree(t7l66xb); - - return ret; - -} - -static struct platform_driver t7l66xb_platform_driver = { - .driver = { - .name = "t7l66xb", - .owner = THIS_MODULE, - }, - .suspend = t7l66xb_suspend, - .resume = t7l66xb_resume, - .probe = t7l66xb_probe, - .remove = t7l66xb_remove, -}; - -/*--------------------------------------------------------------------------*/ - -module_platform_driver(t7l66xb_platform_driver); - -MODULE_DESCRIPTION("Toshiba T7L66XB core driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton"); -MODULE_ALIAS("platform:t7l66xb"); diff --git a/ANDROID_3.4.5/drivers/mfd/tc3589x.c b/ANDROID_3.4.5/drivers/mfd/tc3589x.c deleted file mode 100644 index de979742..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tc3589x.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License, version 2 - * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - */ - -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tc3589x.h> - -#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0 -#define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0) - -/** - * tc3589x_reg_read() - read a single TC3589x register - * @tc3589x: Device to read from - * @reg: Register to read - */ -int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg) -{ - int ret; - - ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg); - if (ret < 0) - dev_err(tc3589x->dev, "failed to read reg %#x: %d\n", - reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(tc3589x_reg_read); - -/** - * tc3589x_reg_read() - write a single TC3589x register - * @tc3589x: Device to write to - * @reg: Register to read - * @data: Value to write - */ -int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data) -{ - int ret; - - ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data); - if (ret < 0) - dev_err(tc3589x->dev, "failed to write reg %#x: %d\n", - reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(tc3589x_reg_write); - -/** - * tc3589x_block_read() - read multiple TC3589x registers - * @tc3589x: Device to read from - * @reg: First register - * @length: Number of registers - * @values: Buffer to write to - */ -int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values) -{ - int ret; - - ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values); - if (ret < 0) - dev_err(tc3589x->dev, "failed to read regs %#x: %d\n", - reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(tc3589x_block_read); - -/** - * tc3589x_block_write() - write multiple TC3589x registers - * @tc3589x: Device to write to - * @reg: First register - * @length: Number of registers - * @values: Values to write - */ -int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length, - const u8 *values) -{ - int ret; - - ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length, - values); - if (ret < 0) - dev_err(tc3589x->dev, "failed to write regs %#x: %d\n", - reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(tc3589x_block_write); - -/** - * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register - * @tc3589x: Device to write to - * @reg: Register to write - * @mask: Mask of bits to set - * @values: Value to set - */ -int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val) -{ - int ret; - - mutex_lock(&tc3589x->lock); - - ret = tc3589x_reg_read(tc3589x, reg); - if (ret < 0) - goto out; - - ret &= ~mask; - ret |= val; - - ret = tc3589x_reg_write(tc3589x, reg, ret); - -out: - mutex_unlock(&tc3589x->lock); - return ret; -} -EXPORT_SYMBOL_GPL(tc3589x_set_bits); - -static struct resource gpio_resources[] = { - { - .start = TC3589x_INT_GPIIRQ, - .end = TC3589x_INT_GPIIRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource keypad_resources[] = { - { - .start = TC3589x_INT_KBDIRQ, - .end = TC3589x_INT_KBDIRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell tc3589x_dev_gpio[] = { - { - .name = "tc3589x-gpio", - .num_resources = ARRAY_SIZE(gpio_resources), - .resources = &gpio_resources[0], - }, -}; - -static struct mfd_cell tc3589x_dev_keypad[] = { - { - .name = "tc3589x-keypad", - .num_resources = ARRAY_SIZE(keypad_resources), - .resources = &keypad_resources[0], - }, -}; - -static irqreturn_t tc3589x_irq(int irq, void *data) -{ - struct tc3589x *tc3589x = data; - int status; - -again: - status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); - if (status < 0) - return IRQ_NONE; - - while (status) { - int bit = __ffs(status); - - handle_nested_irq(tc3589x->irq_base + bit); - status &= ~(1 << bit); - } - - /* - * A dummy read or write (to any register) appears to be necessary to - * have the last interrupt clear (for example, GPIO IC write) take - * effect. In such a case, recheck for any interrupt which is still - * pending. - */ - status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); - if (status) - goto again; - - return IRQ_HANDLED; -} - -static int tc3589x_irq_init(struct tc3589x *tc3589x) -{ - int base = tc3589x->irq_base; - int irq; - - for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { - irq_set_chip_data(irq, tc3589x); - irq_set_chip_and_handler(irq, &dummy_irq_chip, - handle_edge_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - } - - return 0; -} - -static void tc3589x_irq_remove(struct tc3589x *tc3589x) -{ - int base = tc3589x->irq_base; - int irq; - - for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); - } -} - -static int tc3589x_chip_init(struct tc3589x *tc3589x) -{ - int manf, ver, ret; - - manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE); - if (manf < 0) - return manf; - - ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION); - if (ver < 0) - return ver; - - if (manf != TC3589x_MANFCODE_MAGIC) { - dev_err(tc3589x->dev, "unknown manufacturer: %#x\n", manf); - return -EINVAL; - } - - dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x\n", manf, ver); - - /* - * Put everything except the IRQ module into reset; - * also spare the GPIO module for any pin initialization - * done during pre-kernel boot - */ - ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL, - TC3589x_RSTCTRL_TIMRST - | TC3589x_RSTCTRL_ROTRST - | TC3589x_RSTCTRL_KBDRST); - if (ret < 0) - return ret; - - /* Clear the reset interrupt. */ - return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1); -} - -static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) -{ - int ret = 0; - unsigned int blocks = tc3589x->pdata->block; - - if (blocks & TC3589x_BLOCK_GPIO) { - ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, - ARRAY_SIZE(tc3589x_dev_gpio), NULL, - tc3589x->irq_base); - if (ret) { - dev_err(tc3589x->dev, "failed to add gpio child\n"); - return ret; - } - dev_info(tc3589x->dev, "added gpio block\n"); - } - - if (blocks & TC3589x_BLOCK_KEYPAD) { - ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, - ARRAY_SIZE(tc3589x_dev_keypad), NULL, - tc3589x->irq_base); - if (ret) { - dev_err(tc3589x->dev, "failed to keypad child\n"); - return ret; - } - dev_info(tc3589x->dev, "added keypad block\n"); - } - - return ret; -} - -static int __devinit tc3589x_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct tc3589x_platform_data *pdata = i2c->dev.platform_data; - struct tc3589x *tc3589x; - int ret; - - if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA - | I2C_FUNC_SMBUS_I2C_BLOCK)) - return -EIO; - - tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL); - if (!tc3589x) - return -ENOMEM; - - mutex_init(&tc3589x->lock); - - tc3589x->dev = &i2c->dev; - tc3589x->i2c = i2c; - tc3589x->pdata = pdata; - tc3589x->irq_base = pdata->irq_base; - tc3589x->num_gpio = id->driver_data; - - i2c_set_clientdata(i2c, tc3589x); - - ret = tc3589x_chip_init(tc3589x); - if (ret) - goto out_free; - - ret = tc3589x_irq_init(tc3589x); - if (ret) - goto out_free; - - ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "tc3589x", tc3589x); - if (ret) { - dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret); - goto out_removeirq; - } - - ret = tc3589x_device_init(tc3589x); - if (ret) { - dev_err(tc3589x->dev, "failed to add child devices\n"); - goto out_freeirq; - } - - return 0; - -out_freeirq: - free_irq(tc3589x->i2c->irq, tc3589x); -out_removeirq: - tc3589x_irq_remove(tc3589x); -out_free: - kfree(tc3589x); - return ret; -} - -static int __devexit tc3589x_remove(struct i2c_client *client) -{ - struct tc3589x *tc3589x = i2c_get_clientdata(client); - - mfd_remove_devices(tc3589x->dev); - - free_irq(tc3589x->i2c->irq, tc3589x); - tc3589x_irq_remove(tc3589x); - - kfree(tc3589x); - - return 0; -} - -#ifdef CONFIG_PM -static int tc3589x_suspend(struct device *dev) -{ - struct tc3589x *tc3589x = dev_get_drvdata(dev); - struct i2c_client *client = tc3589x->i2c; - int ret = 0; - - /* put the system to sleep mode */ - if (!device_may_wakeup(&client->dev)) - ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, - TC3589x_CLKMODE_MODCTL_SLEEP); - - return ret; -} - -static int tc3589x_resume(struct device *dev) -{ - struct tc3589x *tc3589x = dev_get_drvdata(dev); - struct i2c_client *client = tc3589x->i2c; - int ret = 0; - - /* enable the system into operation */ - if (!device_may_wakeup(&client->dev)) - ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, - TC3589x_CLKMODE_MODCTL_OPERATION); - - return ret; -} - -static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, - tc3589x_resume); -#endif - -static const struct i2c_device_id tc3589x_id[] = { - { "tc3589x", 24 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tc3589x_id); - -static struct i2c_driver tc3589x_driver = { - .driver.name = "tc3589x", - .driver.owner = THIS_MODULE, -#ifdef CONFIG_PM - .driver.pm = &tc3589x_dev_pm_ops, -#endif - .probe = tc3589x_probe, - .remove = __devexit_p(tc3589x_remove), - .id_table = tc3589x_id, -}; - -static int __init tc3589x_init(void) -{ - return i2c_add_driver(&tc3589x_driver); -} -subsys_initcall(tc3589x_init); - -static void __exit tc3589x_exit(void) -{ - i2c_del_driver(&tc3589x_driver); -} -module_exit(tc3589x_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("TC3589x MFD core driver"); -MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); diff --git a/ANDROID_3.4.5/drivers/mfd/tc6387xb.c b/ANDROID_3.4.5/drivers/mfd/tc6387xb.c deleted file mode 100644 index d20a284a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tc6387xb.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Toshiba TC6387XB support - * Copyright (c) 2005 Ian Molton - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This file contains TC6387XB base support. - * - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tmio.h> -#include <linux/mfd/tc6387xb.h> -#include <linux/slab.h> - -enum { - TC6387XB_CELL_MMC, -}; - -struct tc6387xb { - void __iomem *scr; - struct clk *clk32k; - struct resource rscr; -}; - -static struct resource tc6387xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, -}; - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM -static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - struct tc6387xb_platform_data *pdata = dev->dev.platform_data; - - if (pdata && pdata->suspend) - pdata->suspend(dev); - clk_disable(tc6387xb->clk32k); - - return 0; -} - -static int tc6387xb_resume(struct platform_device *dev) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - struct tc6387xb_platform_data *pdata = dev->dev.platform_data; - - clk_enable(tc6387xb->clk32k); - if (pdata && pdata->resume) - pdata->resume(dev); - - tmio_core_mmc_resume(tc6387xb->scr + 0x200, 0, - tc6387xb_mmc_resources[0].start & 0xfffe); - - return 0; -} -#else -#define tc6387xb_suspend NULL -#define tc6387xb_resume NULL -#endif - -/*--------------------------------------------------------------------------*/ - -static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state); -} - -static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state); -} - - -static int tc6387xb_mmc_enable(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - clk_enable(tc6387xb->clk32k); - - tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0, - tc6387xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int tc6387xb_mmc_disable(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - clk_disable(tc6387xb->clk32k); - - return 0; -} - -static struct tmio_mmc_data tc6387xb_mmc_data = { - .hclk = 24000000, - .set_pwr = tc6387xb_mmc_pwr, - .set_clk_div = tc6387xb_mmc_clk_div, -}; - -/*--------------------------------------------------------------------------*/ - -static struct mfd_cell tc6387xb_cells[] = { - [TC6387XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = tc6387xb_mmc_enable, - .disable = tc6387xb_mmc_disable, - .platform_data = &tc6387xb_mmc_data, - .pdata_size = sizeof(tc6387xb_mmc_data), - .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), - .resources = tc6387xb_mmc_resources, - }, -}; - -static int __devinit tc6387xb_probe(struct platform_device *dev) -{ - struct tc6387xb_platform_data *pdata = dev->dev.platform_data; - struct resource *iomem, *rscr; - struct clk *clk32k; - struct tc6387xb *tc6387xb; - int irq, ret; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) { - return -EINVAL; - } - - tc6387xb = kzalloc(sizeof *tc6387xb, GFP_KERNEL); - if (!tc6387xb) - return -ENOMEM; - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - irq = ret; - else - goto err_no_irq; - - clk32k = clk_get(&dev->dev, "CLK_CK32K"); - if (IS_ERR(clk32k)) { - ret = PTR_ERR(clk32k); - goto err_no_clk; - } - - rscr = &tc6387xb->rscr; - rscr->name = "tc6387xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_resource; - - tc6387xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!tc6387xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - tc6387xb->clk32k = clk32k; - platform_set_drvdata(dev, tc6387xb); - - if (pdata && pdata->enable) - pdata->enable(dev); - - printk(KERN_INFO "Toshiba tc6387xb initialised\n"); - - ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, - ARRAY_SIZE(tc6387xb_cells), iomem, irq); - - if (!ret) - return 0; - - iounmap(tc6387xb->scr); -err_ioremap: - release_resource(&tc6387xb->rscr); -err_resource: - clk_put(clk32k); -err_no_clk: -err_no_irq: - kfree(tc6387xb); - return ret; -} - -static int __devexit tc6387xb_remove(struct platform_device *dev) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - mfd_remove_devices(&dev->dev); - iounmap(tc6387xb->scr); - release_resource(&tc6387xb->rscr); - clk_disable(tc6387xb->clk32k); - clk_put(tc6387xb->clk32k); - platform_set_drvdata(dev, NULL); - kfree(tc6387xb); - - return 0; -} - - -static struct platform_driver tc6387xb_platform_driver = { - .driver = { - .name = "tc6387xb", - }, - .probe = tc6387xb_probe, - .remove = __devexit_p(tc6387xb_remove), - .suspend = tc6387xb_suspend, - .resume = tc6387xb_resume, -}; - -module_platform_driver(tc6387xb_platform_driver); - -MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton"); -MODULE_ALIAS("platform:tc6387xb"); - diff --git a/ANDROID_3.4.5/drivers/mfd/tc6393xb.c b/ANDROID_3.4.5/drivers/mfd/tc6393xb.c deleted file mode 100644 index 9612264f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tc6393xb.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * Toshiba TC6393XB SoC support - * - * Copyright(c) 2005-2006 Chris Humbert - * Copyright(c) 2005 Dirk Opfer - * Copyright(c) 2005 Ian Molton <spyro@f2s.com> - * Copyright(c) 2007 Dmitry Baryshkov - * - * Based on code written by Sharp/Lineo for 2.4 kernels - * Based on locomo.c - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tmio.h> -#include <linux/mfd/tc6393xb.h> -#include <linux/gpio.h> -#include <linux/slab.h> - -#define SCR_REVID 0x08 /* b Revision ID */ -#define SCR_ISR 0x50 /* b Interrupt Status */ -#define SCR_IMR 0x52 /* b Interrupt Mask */ -#define SCR_IRR 0x54 /* b Interrupt Routing */ -#define SCR_GPER 0x60 /* w GP Enable */ -#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */ -#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */ -#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */ -#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */ -#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */ -#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */ -#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */ -#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */ -#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */ -#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */ -#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */ -#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */ -#define SCR_CCR 0x98 /* w Clock Control */ -#define SCR_PLL2CR 0x9a /* w PLL2 Control */ -#define SCR_PLL1CR 0x9c /* l PLL1 Control */ -#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */ -#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */ -#define SCR_FER 0xe0 /* b Function Enable */ -#define SCR_MCR 0xe4 /* w Mode Control */ -#define SCR_CONFIG 0xfc /* b Configuration Control */ -#define SCR_DEBUG 0xff /* b Debug */ - -#define SCR_CCR_CK32K BIT(0) -#define SCR_CCR_USBCK BIT(1) -#define SCR_CCR_UNK1 BIT(4) -#define SCR_CCR_MCLK_MASK (7 << 8) -#define SCR_CCR_MCLK_OFF (0 << 8) -#define SCR_CCR_MCLK_12 (1 << 8) -#define SCR_CCR_MCLK_24 (2 << 8) -#define SCR_CCR_MCLK_48 (3 << 8) -#define SCR_CCR_HCLK_MASK (3 << 12) -#define SCR_CCR_HCLK_24 (0 << 12) -#define SCR_CCR_HCLK_48 (1 << 12) - -#define SCR_FER_USBEN BIT(0) /* USB host enable */ -#define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */ -#define SCR_FER_SLCDEN BIT(2) /* SLCD enable */ - -#define SCR_MCR_RDY_MASK (3 << 0) -#define SCR_MCR_RDY_OPENDRAIN (0 << 0) -#define SCR_MCR_RDY_TRISTATE (1 << 0) -#define SCR_MCR_RDY_PUSHPULL (2 << 0) -#define SCR_MCR_RDY_UNK BIT(2) -#define SCR_MCR_RDY_EN BIT(3) -#define SCR_MCR_INT_MASK (3 << 4) -#define SCR_MCR_INT_OPENDRAIN (0 << 4) -#define SCR_MCR_INT_TRISTATE (1 << 4) -#define SCR_MCR_INT_PUSHPULL (2 << 4) -#define SCR_MCR_INT_UNK BIT(6) -#define SCR_MCR_INT_EN BIT(7) -/* bits 8 - 16 are unknown */ - -#define TC_GPIO_BIT(i) (1 << (i & 0x7)) - -/*--------------------------------------------------------------------------*/ - -struct tc6393xb { - void __iomem *scr; - - struct gpio_chip gpio; - - struct clk *clk; /* 3,6 Mhz */ - - spinlock_t lock; /* protects RMW cycles */ - - struct { - u8 fer; - u16 ccr; - u8 gpi_bcr[3]; - u8 gpo_dsr[3]; - u8 gpo_doecr[3]; - } suspend_state; - - struct resource rscr; - struct resource *iomem; - int irq; - int irq_base; -}; - -enum { - TC6393XB_CELL_NAND, - TC6393XB_CELL_MMC, - TC6393XB_CELL_OHCI, - TC6393XB_CELL_FB, -}; - -/*--------------------------------------------------------------------------*/ - -static int tc6393xb_nand_enable(struct platform_device *nand) -{ - struct platform_device *dev = to_platform_device(nand->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - /* SMD buffer on */ - dev_dbg(&dev->dev, "SMD buffer on\n"); - tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static struct resource __devinitdata tc6393xb_nand_resources[] = { - { - .start = 0x1000, - .end = 0x1007, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0100, - .end = 0x01ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_NAND, - .end = IRQ_TC6393_NAND, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tc6393xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_MMC, - .end = IRQ_TC6393_MMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource tc6393xb_ohci_resources[] = { - { - .start = 0x3000, - .end = 0x31ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0300, - .end = 0x03ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x010000, - .end = 0x017fff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x018000, - .end = 0x01ffff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_OHCI, - .end = IRQ_TC6393_OHCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource __devinitdata tc6393xb_fb_resources[] = { - { - .start = 0x5000, - .end = 0x51ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0500, - .end = 0x05ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x100000, - .end = 0x1fffff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_FB, - .end = IRQ_TC6393_FB, - .flags = IORESOURCE_IRQ, - }, -}; - -static int tc6393xb_ohci_enable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - u8 fer; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr |= SCR_CCR_USBCK; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - fer = tmio_ioread8(tc6393xb->scr + SCR_FER); - fer |= SCR_FER_USBEN; - tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_ohci_disable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - u8 fer; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - fer = tmio_ioread8(tc6393xb->scr + SCR_FER); - fer &= ~SCR_FER_USBEN; - tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_USBCK; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_fb_enable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_MCLK_MASK; - ccr |= SCR_CCR_MCLK_48; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_fb_disable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_MCLK_MASK; - ccr |= SCR_CCR_MCLK_OFF; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) -{ - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - u8 fer; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - fer = ioread8(tc6393xb->scr + SCR_FER); - if (on) - fer |= SCR_FER_SLCDEN; - else - fer &= ~SCR_FER_SLCDEN; - iowrite8(fer, tc6393xb->scr + SCR_FER); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} -EXPORT_SYMBOL(tc6393xb_lcd_set_power); - -int tc6393xb_lcd_mode(struct platform_device *fb, - const struct fb_videomode *mode) { - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); - iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} -EXPORT_SYMBOL(tc6393xb_lcd_mode); - -static int tc6393xb_mmc_enable(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - - tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0, - tc6393xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int tc6393xb_mmc_resume(struct platform_device *mmc) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - - tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0, - tc6393xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - - tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state); -} - -static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - - tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state); -} - -static struct tmio_mmc_data tc6393xb_mmc_data = { - .hclk = 24000000, - .set_pwr = tc6393xb_mmc_pwr, - .set_clk_div = tc6393xb_mmc_clk_div, -}; - -static struct mfd_cell __devinitdata tc6393xb_cells[] = { - [TC6393XB_CELL_NAND] = { - .name = "tmio-nand", - .enable = tc6393xb_nand_enable, - .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), - .resources = tc6393xb_nand_resources, - }, - [TC6393XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = tc6393xb_mmc_enable, - .resume = tc6393xb_mmc_resume, - .platform_data = &tc6393xb_mmc_data, - .pdata_size = sizeof(tc6393xb_mmc_data), - .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), - .resources = tc6393xb_mmc_resources, - }, - [TC6393XB_CELL_OHCI] = { - .name = "tmio-ohci", - .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), - .resources = tc6393xb_ohci_resources, - .enable = tc6393xb_ohci_enable, - .suspend = tc6393xb_ohci_disable, - .resume = tc6393xb_ohci_enable, - .disable = tc6393xb_ohci_disable, - }, - [TC6393XB_CELL_FB] = { - .name = "tmio-fb", - .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), - .resources = tc6393xb_fb_resources, - .enable = tc6393xb_fb_enable, - .suspend = tc6393xb_fb_disable, - .resume = tc6393xb_fb_enable, - .disable = tc6393xb_fb_disable, - }, -}; - -/*--------------------------------------------------------------------------*/ - -static int tc6393xb_gpio_get(struct gpio_chip *chip, - unsigned offset) -{ - struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); - - /* XXX: does dsr also represent inputs? */ - return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) - & TC_GPIO_BIT(offset); -} - -static void __tc6393xb_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); - u8 dsr; - - dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); - if (value) - dsr |= TC_GPIO_BIT(offset); - else - dsr &= ~TC_GPIO_BIT(offset); - - tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); -} - -static void tc6393xb_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - __tc6393xb_gpio_set(chip, offset, value); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); - unsigned long flags; - u8 doecr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - doecr &= ~TC_GPIO_BIT(offset); - tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); - unsigned long flags; - u8 doecr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - - __tc6393xb_gpio_set(chip, offset, value); - - doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - doecr |= TC_GPIO_BIT(offset); - tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base) -{ - tc6393xb->gpio.label = "tc6393xb"; - tc6393xb->gpio.base = gpio_base; - tc6393xb->gpio.ngpio = 16; - tc6393xb->gpio.set = tc6393xb_gpio_set; - tc6393xb->gpio.get = tc6393xb_gpio_get; - tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input; - tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output; - - return gpiochip_add(&tc6393xb->gpio); -} - -/*--------------------------------------------------------------------------*/ - -static void -tc6393xb_irq(unsigned int irq, struct irq_desc *desc) -{ - struct tc6393xb *tc6393xb = irq_get_handler_data(irq); - unsigned int isr; - unsigned int i, irq_base; - - irq_base = tc6393xb->irq_base; - - while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & - ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) - for (i = 0; i < TC6393XB_NR_IRQS; i++) { - if (isr & (1 << i)) - generic_handle_irq(irq_base + i); - } -} - -static void tc6393xb_irq_ack(struct irq_data *data) -{ -} - -static void tc6393xb_irq_mask(struct irq_data *data) -{ - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr |= 1 << (data->irq - tc6393xb->irq_base); - tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); - spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static void tc6393xb_irq_unmask(struct irq_data *data) -{ - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - spin_lock_irqsave(&tc6393xb->lock, flags); - imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - tc6393xb->irq_base)); - tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); - spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static struct irq_chip tc6393xb_chip = { - .name = "tc6393xb", - .irq_ack = tc6393xb_irq_ack, - .irq_mask = tc6393xb_irq_mask, - .irq_unmask = tc6393xb_irq_unmask, -}; - -static void tc6393xb_attach_irq(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = tc6393xb->irq_base; - - for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); - irq_set_chip_data(irq, tc6393xb); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_handler_data(tc6393xb->irq, tc6393xb); - irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq); -} - -static void tc6393xb_detach_irq(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_set_chained_handler(tc6393xb->irq, NULL); - irq_set_handler_data(tc6393xb->irq, NULL); - - irq_base = tc6393xb->irq_base; - - for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { - set_irq_flags(irq, 0); - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); - } -} - -/*--------------------------------------------------------------------------*/ - -static int __devinit tc6393xb_probe(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb; - struct resource *iomem, *rscr; - int ret, temp; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) - return -EINVAL; - - tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); - if (!tc6393xb) { - ret = -ENOMEM; - goto err_kzalloc; - } - - spin_lock_init(&tc6393xb->lock); - - platform_set_drvdata(dev, tc6393xb); - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - tc6393xb->irq = ret; - else - goto err_noirq; - - tc6393xb->iomem = iomem; - tc6393xb->irq_base = tcpd->irq_base; - - tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); - if (IS_ERR(tc6393xb->clk)) { - ret = PTR_ERR(tc6393xb->clk); - goto err_clk_get; - } - - rscr = &tc6393xb->rscr; - rscr->name = "tc6393xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_request_scr; - - tc6393xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!tc6393xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - ret = clk_enable(tc6393xb->clk); - if (ret) - goto err_clk_enable; - - ret = tcpd->enable(dev); - if (ret) - goto err_enable; - - iowrite8(0, tc6393xb->scr + SCR_FER); - iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); - iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, - tc6393xb->scr + SCR_CCR); - iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | - SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | - BIT(15), tc6393xb->scr + SCR_MCR); - iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); - iowrite8(0, tc6393xb->scr + SCR_IRR); - iowrite8(0xbf, tc6393xb->scr + SCR_IMR); - - printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", - tmio_ioread8(tc6393xb->scr + SCR_REVID), - (unsigned long) iomem->start, tc6393xb->irq); - - tc6393xb->gpio.base = -1; - - if (tcpd->gpio_base >= 0) { - ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); - if (ret) - goto err_gpio_add; - } - - tc6393xb_attach_irq(dev); - - if (tcpd->setup) { - ret = tcpd->setup(dev); - if (ret) - goto err_setup; - } - - tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data; - tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size = - sizeof(*tcpd->nand_data); - tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data; - tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); - - ret = mfd_add_devices(&dev->dev, dev->id, - tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), - iomem, tcpd->irq_base); - - if (!ret) - return 0; - - if (tcpd->teardown) - tcpd->teardown(dev); - -err_setup: - tc6393xb_detach_irq(dev); - -err_gpio_add: - if (tc6393xb->gpio.base != -1) - temp = gpiochip_remove(&tc6393xb->gpio); - tcpd->disable(dev); -err_enable: - clk_disable(tc6393xb->clk); -err_clk_enable: - iounmap(tc6393xb->scr); -err_ioremap: - release_resource(&tc6393xb->rscr); -err_request_scr: - clk_put(tc6393xb->clk); -err_noirq: -err_clk_get: - kfree(tc6393xb); -err_kzalloc: - return ret; -} - -static int __devexit tc6393xb_remove(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int ret; - - mfd_remove_devices(&dev->dev); - - if (tcpd->teardown) - tcpd->teardown(dev); - - tc6393xb_detach_irq(dev); - - if (tc6393xb->gpio.base != -1) { - ret = gpiochip_remove(&tc6393xb->gpio); - if (ret) { - dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret); - return ret; - } - } - - ret = tcpd->disable(dev); - clk_disable(tc6393xb->clk); - iounmap(tc6393xb->scr); - release_resource(&tc6393xb->rscr); - platform_set_drvdata(dev, NULL); - clk_put(tc6393xb->clk); - kfree(tc6393xb); - - return ret; -} - -#ifdef CONFIG_PM -static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int i, ret; - - tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); - tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); - - for (i = 0; i < 3; i++) { - tc6393xb->suspend_state.gpo_dsr[i] = - ioread8(tc6393xb->scr + SCR_GPO_DSR(i)); - tc6393xb->suspend_state.gpo_doecr[i] = - ioread8(tc6393xb->scr + SCR_GPO_DOECR(i)); - tc6393xb->suspend_state.gpi_bcr[i] = - ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); - } - ret = tcpd->suspend(dev); - clk_disable(tc6393xb->clk); - - return ret; -} - -static int tc6393xb_resume(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int ret; - int i; - - clk_enable(tc6393xb->clk); - - ret = tcpd->resume(dev); - if (ret) - return ret; - - if (!tcpd->resume_restore) - return 0; - - iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); - iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); - iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); - iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | - SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | - BIT(15), tc6393xb->scr + SCR_MCR); - iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); - iowrite8(0, tc6393xb->scr + SCR_IRR); - iowrite8(0xbf, tc6393xb->scr + SCR_IMR); - - for (i = 0; i < 3; i++) { - iowrite8(tc6393xb->suspend_state.gpo_dsr[i], - tc6393xb->scr + SCR_GPO_DSR(i)); - iowrite8(tc6393xb->suspend_state.gpo_doecr[i], - tc6393xb->scr + SCR_GPO_DOECR(i)); - iowrite8(tc6393xb->suspend_state.gpi_bcr[i], - tc6393xb->scr + SCR_GPI_BCR(i)); - } - - return 0; -} -#else -#define tc6393xb_suspend NULL -#define tc6393xb_resume NULL -#endif - -static struct platform_driver tc6393xb_driver = { - .probe = tc6393xb_probe, - .remove = __devexit_p(tc6393xb_remove), - .suspend = tc6393xb_suspend, - .resume = tc6393xb_resume, - - .driver = { - .name = "tc6393xb", - .owner = THIS_MODULE, - }, -}; - -static int __init tc6393xb_init(void) -{ - return platform_driver_register(&tc6393xb_driver); -} - -static void __exit tc6393xb_exit(void) -{ - platform_driver_unregister(&tc6393xb_driver); -} - -subsys_initcall(tc6393xb_init); -module_exit(tc6393xb_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); -MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); -MODULE_ALIAS("platform:tc6393xb"); - diff --git a/ANDROID_3.4.5/drivers/mfd/ti-ssp.c b/ANDROID_3.4.5/drivers/mfd/ti-ssp.c deleted file mode 100644 index 4fb0e6c8..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ti-ssp.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs - * - * Copyright (C) 2010 Texas Instruments Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/wait.h> -#include <linux/clk.h> -#include <linux/interrupt.h> -#include <linux/device.h> -#include <linux/spinlock.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/mfd/core.h> -#include <linux/mfd/ti_ssp.h> - -/* Register Offsets */ -#define REG_REV 0x00 -#define REG_IOSEL_1 0x04 -#define REG_IOSEL_2 0x08 -#define REG_PREDIV 0x0c -#define REG_INTR_ST 0x10 -#define REG_INTR_EN 0x14 -#define REG_TEST_CTRL 0x18 - -/* Per port registers */ -#define PORT_CFG_2 0x00 -#define PORT_ADDR 0x04 -#define PORT_DATA 0x08 -#define PORT_CFG_1 0x0c -#define PORT_STATE 0x10 - -#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) -#define SSP_PORT_CLKRATE_MASK 0x0f - -#define SSP_SEQRAM_WR_EN BIT(4) -#define SSP_SEQRAM_RD_EN BIT(5) -#define SSP_START BIT(15) -#define SSP_BUSY BIT(10) -#define SSP_PORT_ASL BIT(7) -#define SSP_PORT_CFO1 BIT(6) - -#define SSP_PORT_SEQRAM_SIZE 32 - -static const int ssp_port_base[] = {0x040, 0x080}; -static const int ssp_port_seqram[] = {0x100, 0x180}; - -struct ti_ssp { - struct resource *res; - struct device *dev; - void __iomem *regs; - spinlock_t lock; - struct clk *clk; - int irq; - wait_queue_head_t wqh; - - /* - * Some of the iosel2 register bits always read-back as 0, we need to - * remember these values so that we don't clobber previously set - * values. - */ - u32 iosel2; -}; - -static inline struct ti_ssp *dev_to_ssp(struct device *dev) -{ - return dev_get_drvdata(dev->parent); -} - -static inline int dev_to_port(struct device *dev) -{ - return to_platform_device(dev)->id; -} - -/* Register Access Helpers, rmw() functions need to run locked */ -static inline u32 ssp_read(struct ti_ssp *ssp, int reg) -{ - return __raw_readl(ssp->regs + reg); -} - -static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) -{ - __raw_writel(val, ssp->regs + reg); -} - -static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) -{ - ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits); -} - -static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg) -{ - return ssp_read(ssp, ssp_port_base[port] + reg); -} - -static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg, - u32 val) -{ - ssp_write(ssp, ssp_port_base[port] + reg, val); -} - -static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg, - u32 mask, u32 bits) -{ - ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits); -} - -static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg, - u32 bits) -{ - ssp_port_rmw(ssp, port, reg, bits, 0); -} - -static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg, - u32 bits) -{ - ssp_port_rmw(ssp, port, reg, 0, bits); -} - -/* Called to setup port clock mode, caller must hold ssp->lock */ -static int __set_mode(struct ti_ssp *ssp, int port, int mode) -{ - mode &= SSP_PORT_CONFIG_MASK; - ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode); - - return 0; -} - -int ti_ssp_set_mode(struct device *dev, int mode) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev); - int ret; - - spin_lock(&ssp->lock); - ret = __set_mode(ssp, port, mode); - spin_unlock(&ssp->lock); - - return ret; -} -EXPORT_SYMBOL(ti_ssp_set_mode); - -/* Called to setup iosel2, caller must hold ssp->lock */ -static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val) -{ - ssp->iosel2 = (ssp->iosel2 & ~mask) | val; - ssp_write(ssp, REG_IOSEL_2, ssp->iosel2); -} - -/* Called to setup port iosel, caller must hold ssp->lock */ -static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) -{ - unsigned val, shift = port ? 16 : 0; - - /* IOSEL1 gets the least significant 16 bits */ - val = ssp_read(ssp, REG_IOSEL_1); - val &= 0xffff << (port ? 0 : 16); - val |= (iosel & 0xffff) << (port ? 16 : 0); - ssp_write(ssp, REG_IOSEL_1, val); - - /* IOSEL2 gets the most significant 16 bits */ - val = (iosel >> 16) & 0x7; - __set_iosel2(ssp, 0x7 << shift, val << shift); -} - -int ti_ssp_set_iosel(struct device *dev, u32 iosel) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev); - - spin_lock(&ssp->lock); - __set_iosel(ssp, port, iosel); - spin_unlock(&ssp->lock); - - return 0; -} -EXPORT_SYMBOL(ti_ssp_set_iosel); - -int ti_ssp_load(struct device *dev, int offs, u32* prog, int len) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev); - int i; - - if (len > SSP_PORT_SEQRAM_SIZE) - return -ENOSPC; - - spin_lock(&ssp->lock); - - /* Enable SeqRAM access */ - ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); - - /* Copy code */ - for (i = 0; i < len; i++) { - __raw_writel(prog[i], ssp->regs + offs + 4*i + - ssp_port_seqram[port]); - } - - /* Disable SeqRAM access */ - ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); - - spin_unlock(&ssp->lock); - - return 0; -} -EXPORT_SYMBOL(ti_ssp_load); - -int ti_ssp_raw_read(struct device *dev) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev); - int shift = port ? 27 : 11; - - return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf; -} -EXPORT_SYMBOL(ti_ssp_raw_read); - -int ti_ssp_raw_write(struct device *dev, u32 val) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev), shift; - - spin_lock(&ssp->lock); - - shift = port ? 22 : 6; - val &= 0xf; - __set_iosel2(ssp, 0xf << shift, val << shift); - - spin_unlock(&ssp->lock); - - return 0; -} -EXPORT_SYMBOL(ti_ssp_raw_write); - -static inline int __xfer_done(struct ti_ssp *ssp, int port) -{ - return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY); -} - -int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) -{ - struct ti_ssp *ssp = dev_to_ssp(dev); - int port = dev_to_port(dev); - int ret; - - if (pc & ~(0x3f)) - return -EINVAL; - - /* Grab ssp->lock to serialize rmw on ssp registers */ - spin_lock(&ssp->lock); - - ssp_port_write(ssp, port, PORT_ADDR, input >> 16); - ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); - ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); - - /* grab wait queue head lock to avoid race with the isr */ - spin_lock_irq(&ssp->wqh.lock); - - /* kick off sequence execution in hardware */ - ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); - - /* drop ssp lock; no register writes beyond this */ - spin_unlock(&ssp->lock); - - ret = wait_event_interruptible_locked_irq(ssp->wqh, - __xfer_done(ssp, port)); - spin_unlock_irq(&ssp->wqh.lock); - - if (ret < 0) - return ret; - - if (output) { - *output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | - (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); - } - - ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */ - - return ret; -} -EXPORT_SYMBOL(ti_ssp_run); - -static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data) -{ - struct ti_ssp *ssp = dev_data; - - spin_lock(&ssp->wqh.lock); - - ssp_write(ssp, REG_INTR_ST, 0x3); - wake_up_locked(&ssp->wqh); - - spin_unlock(&ssp->wqh.lock); - - return IRQ_HANDLED; -} - -static int __devinit ti_ssp_probe(struct platform_device *pdev) -{ - static struct ti_ssp *ssp; - const struct ti_ssp_data *pdata = pdev->dev.platform_data; - int error = 0, prediv = 0xff, id; - unsigned long sysclk; - struct device *dev = &pdev->dev; - struct mfd_cell cells[2]; - - ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); - if (!ssp) { - dev_err(dev, "cannot allocate device info\n"); - return -ENOMEM; - } - - ssp->dev = dev; - dev_set_drvdata(dev, ssp); - - ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!ssp->res) { - error = -ENODEV; - dev_err(dev, "cannot determine register area\n"); - goto error_res; - } - - if (!request_mem_region(ssp->res->start, resource_size(ssp->res), - pdev->name)) { - error = -ENOMEM; - dev_err(dev, "cannot claim register memory\n"); - goto error_res; - } - - ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); - if (!ssp->regs) { - error = -ENOMEM; - dev_err(dev, "cannot map register memory\n"); - goto error_map; - } - - ssp->clk = clk_get(dev, NULL); - if (IS_ERR(ssp->clk)) { - error = PTR_ERR(ssp->clk); - dev_err(dev, "cannot claim device clock\n"); - goto error_clk; - } - - ssp->irq = platform_get_irq(pdev, 0); - if (ssp->irq < 0) { - error = -ENODEV; - dev_err(dev, "unknown irq\n"); - goto error_irq; - } - - error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0, - dev_name(dev), ssp); - if (error < 0) { - dev_err(dev, "cannot acquire irq\n"); - goto error_irq; - } - - spin_lock_init(&ssp->lock); - init_waitqueue_head(&ssp->wqh); - - /* Power on and initialize SSP */ - error = clk_enable(ssp->clk); - if (error) { - dev_err(dev, "cannot enable device clock\n"); - goto error_enable; - } - - /* Reset registers to a sensible known state */ - ssp_write(ssp, REG_IOSEL_1, 0); - ssp_write(ssp, REG_IOSEL_2, 0); - ssp_write(ssp, REG_INTR_EN, 0x3); - ssp_write(ssp, REG_INTR_ST, 0x3); - ssp_write(ssp, REG_TEST_CTRL, 0); - ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL); - ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL); - ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1); - ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1); - - sysclk = clk_get_rate(ssp->clk); - if (pdata && pdata->out_clock) - prediv = (sysclk / pdata->out_clock) - 1; - prediv = clamp(prediv, 0, 0xff); - ssp_rmw(ssp, REG_PREDIV, 0xff, prediv); - - memset(cells, 0, sizeof(cells)); - for (id = 0; id < 2; id++) { - const struct ti_ssp_dev_data *data = &pdata->dev_data[id]; - - cells[id].id = id; - cells[id].name = data->dev_name; - cells[id].platform_data = data->pdata; - cells[id].data_size = data->pdata_size; - } - - error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); - if (error < 0) { - dev_err(dev, "cannot add mfd cells\n"); - goto error_enable; - } - - return 0; - -error_enable: - free_irq(ssp->irq, ssp); -error_irq: - clk_put(ssp->clk); -error_clk: - iounmap(ssp->regs); -error_map: - release_mem_region(ssp->res->start, resource_size(ssp->res)); -error_res: - kfree(ssp); - return error; -} - -static int __devexit ti_ssp_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct ti_ssp *ssp = dev_get_drvdata(dev); - - mfd_remove_devices(dev); - clk_disable(ssp->clk); - free_irq(ssp->irq, ssp); - clk_put(ssp->clk); - iounmap(ssp->regs); - release_mem_region(ssp->res->start, resource_size(ssp->res)); - kfree(ssp); - dev_set_drvdata(dev, NULL); - return 0; -} - -static struct platform_driver ti_ssp_driver = { - .probe = ti_ssp_probe, - .remove = __devexit_p(ti_ssp_remove), - .driver = { - .name = "ti-ssp", - .owner = THIS_MODULE, - } -}; - -module_platform_driver(ti_ssp_driver); - -MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); -MODULE_AUTHOR("Cyril Chemparathy"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ti-ssp"); diff --git a/ANDROID_3.4.5/drivers/mfd/timberdale.c b/ANDROID_3.4.5/drivers/mfd/timberdale.c deleted file mode 100644 index 0ba26fb1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/timberdale.c +++ /dev/null @@ -1,904 +0,0 @@ -/* - * timberdale.c timberdale FPGA MFD driver - * Copyright (c) 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Supports: - * Timberdale FPGA - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/msi.h> -#include <linux/mfd/core.h> -#include <linux/slab.h> - -#include <linux/timb_gpio.h> - -#include <linux/i2c.h> -#include <linux/i2c-ocores.h> -#include <linux/i2c-xiic.h> -#include <linux/i2c/tsc2007.h> - -#include <linux/spi/spi.h> -#include <linux/spi/xilinx_spi.h> -#include <linux/spi/max7301.h> -#include <linux/spi/mc33880.h> - -#include <media/timb_radio.h> -#include <media/timb_video.h> - -#include <linux/timb_dma.h> - -#include <linux/ks8842.h> - -#include "timberdale.h" - -#define DRIVER_NAME "timberdale" - -struct timberdale_device { - resource_size_t ctl_mapbase; - unsigned char __iomem *ctl_membase; - struct { - u32 major; - u32 minor; - u32 config; - } fw; -}; - -/*--------------------------------------------------------------------------*/ - -static struct tsc2007_platform_data timberdale_tsc2007_platform_data = { - .model = 2003, - .x_plate_ohms = 100 -}; - -static struct i2c_board_info timberdale_i2c_board_info[] = { - { - I2C_BOARD_INFO("tsc2007", 0x48), - .platform_data = &timberdale_tsc2007_platform_data, - .irq = IRQ_TIMBERDALE_TSC_INT - }, -}; - -static __devinitdata struct xiic_i2c_platform_data -timberdale_xiic_platform_data = { - .devices = timberdale_i2c_board_info, - .num_devices = ARRAY_SIZE(timberdale_i2c_board_info) -}; - -static __devinitdata struct ocores_i2c_platform_data -timberdale_ocores_platform_data = { - .regstep = 4, - .clock_khz = 62500, - .devices = timberdale_i2c_board_info, - .num_devices = ARRAY_SIZE(timberdale_i2c_board_info) -}; - -static const __devinitconst struct resource timberdale_xiic_resources[] = { - { - .start = XIICOFFSET, - .end = XIICEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_I2C, - .end = IRQ_TIMBERDALE_I2C, - .flags = IORESOURCE_IRQ, - }, -}; - -static const __devinitconst struct resource timberdale_ocores_resources[] = { - { - .start = OCORESOFFSET, - .end = OCORESEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_I2C, - .end = IRQ_TIMBERDALE_I2C, - .flags = IORESOURCE_IRQ, - }, -}; - -const struct max7301_platform_data timberdale_max7301_platform_data = { - .base = 200 -}; - -const struct mc33880_platform_data timberdale_mc33880_platform_data = { - .base = 100 -}; - -static struct spi_board_info timberdale_spi_16bit_board_info[] = { - { - .modalias = "max7301", - .max_speed_hz = 26000, - .chip_select = 2, - .mode = SPI_MODE_0, - .platform_data = &timberdale_max7301_platform_data - }, -}; - -static struct spi_board_info timberdale_spi_8bit_board_info[] = { - { - .modalias = "mc33880", - .max_speed_hz = 4000, - .chip_select = 1, - .mode = SPI_MODE_1, - .platform_data = &timberdale_mc33880_platform_data - }, -}; - -static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = { - .num_chipselect = 3, - .little_endian = true, - /* bits per word and devices will be filled in runtime depending - * on the HW config - */ -}; - -static const __devinitconst struct resource timberdale_spi_resources[] = { - { - .start = SPIOFFSET, - .end = SPIEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_SPI, - .end = IRQ_TIMBERDALE_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct ks8842_platform_data - timberdale_ks8842_platform_data = { - .rx_dma_channel = DMA_ETH_RX, - .tx_dma_channel = DMA_ETH_TX -}; - -static const __devinitconst struct resource timberdale_eth_resources[] = { - { - .start = ETHOFFSET, - .end = ETHEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_ETHSW_IF, - .end = IRQ_TIMBERDALE_ETHSW_IF, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct timbgpio_platform_data - timberdale_gpio_platform_data = { - .gpio_base = 0, - .nr_pins = GPIO_NR_PINS, - .irq_base = 200, -}; - -static const __devinitconst struct resource timberdale_gpio_resources[] = { - { - .start = GPIOOFFSET, - .end = GPIOEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_GPIO, - .end = IRQ_TIMBERDALE_GPIO, - .flags = IORESOURCE_IRQ, - }, -}; - -static const __devinitconst struct resource timberdale_mlogicore_resources[] = { - { - .start = MLCOREOFFSET, - .end = MLCOREEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_MLCORE, - .end = IRQ_TIMBERDALE_MLCORE, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_TIMBERDALE_MLCORE_BUF, - .end = IRQ_TIMBERDALE_MLCORE_BUF, - .flags = IORESOURCE_IRQ, - }, -}; - -static const __devinitconst struct resource timberdale_uart_resources[] = { - { - .start = UARTOFFSET, - .end = UARTEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_UART, - .end = IRQ_TIMBERDALE_UART, - .flags = IORESOURCE_IRQ, - }, -}; - -static const __devinitconst struct resource timberdale_uartlite_resources[] = { - { - .start = UARTLITEOFFSET, - .end = UARTLITEEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_UARTLITE, - .end = IRQ_TIMBERDALE_UARTLITE, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct i2c_board_info timberdale_adv7180_i2c_board_info = { - /* Requires jumper JP9 to be off */ - I2C_BOARD_INFO("adv7180", 0x42 >> 1), - .irq = IRQ_TIMBERDALE_ADV7180 -}; - -static __devinitdata struct timb_video_platform_data - timberdale_video_platform_data = { - .dma_channel = DMA_VIDEO_RX, - .i2c_adapter = 0, - .encoder = { - .info = &timberdale_adv7180_i2c_board_info - } -}; - -static const __devinitconst struct resource -timberdale_radio_resources[] = { - { - .start = RDSOFFSET, - .end = RDSEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_RDS, - .end = IRQ_TIMBERDALE_RDS, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct i2c_board_info timberdale_tef6868_i2c_board_info = { - I2C_BOARD_INFO("tef6862", 0x60) -}; - -static __devinitdata struct i2c_board_info timberdale_saa7706_i2c_board_info = { - I2C_BOARD_INFO("saa7706h", 0x1C) -}; - -static __devinitdata struct timb_radio_platform_data - timberdale_radio_platform_data = { - .i2c_adapter = 0, - .tuner = &timberdale_tef6868_i2c_board_info, - .dsp = &timberdale_saa7706_i2c_board_info -}; - -static const __devinitconst struct resource timberdale_video_resources[] = { - { - .start = LOGIWOFFSET, - .end = LOGIWEND, - .flags = IORESOURCE_MEM, - }, - /* - note that the "frame buffer" is located in DMA area - starting at 0x1200000 - */ -}; - -static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = { - .nr_channels = 10, - .channels = { - { - /* UART RX */ - .rx = true, - .descriptors = 2, - .descriptor_elements = 1 - }, - { - /* UART TX */ - .rx = false, - .descriptors = 2, - .descriptor_elements = 1 - }, - { - /* MLB RX */ - .rx = true, - .descriptors = 2, - .descriptor_elements = 1 - }, - { - /* MLB TX */ - .rx = false, - .descriptors = 2, - .descriptor_elements = 1 - }, - { - /* Video RX */ - .rx = true, - .bytes_per_line = 1440, - .descriptors = 2, - .descriptor_elements = 16 - }, - { - /* Video framedrop */ - }, - { - /* SDHCI RX */ - .rx = true, - }, - { - /* SDHCI TX */ - }, - { - /* ETH RX */ - .rx = true, - .descriptors = 2, - .descriptor_elements = 1 - }, - { - /* ETH TX */ - .rx = false, - .descriptors = 2, - .descriptor_elements = 1 - }, - } -}; - -static const __devinitconst struct resource timberdale_dma_resources[] = { - { - .start = DMAOFFSET, - .end = DMAEND, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_DMA, - .end = IRQ_TIMBERDALE_DMA, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = { - { - .name = "timb-dma", - .num_resources = ARRAY_SIZE(timberdale_dma_resources), - .resources = timberdale_dma_resources, - .platform_data = &timb_dma_platform_data, - .pdata_size = sizeof(timb_dma_platform_data), - }, - { - .name = "timb-uart", - .num_resources = ARRAY_SIZE(timberdale_uart_resources), - .resources = timberdale_uart_resources, - }, - { - .name = "xiic-i2c", - .num_resources = ARRAY_SIZE(timberdale_xiic_resources), - .resources = timberdale_xiic_resources, - .platform_data = &timberdale_xiic_platform_data, - .pdata_size = sizeof(timberdale_xiic_platform_data), - }, - { - .name = "timb-gpio", - .num_resources = ARRAY_SIZE(timberdale_gpio_resources), - .resources = timberdale_gpio_resources, - .platform_data = &timberdale_gpio_platform_data, - .pdata_size = sizeof(timberdale_gpio_platform_data), - }, - { - .name = "timb-video", - .num_resources = ARRAY_SIZE(timberdale_video_resources), - .resources = timberdale_video_resources, - .platform_data = &timberdale_video_platform_data, - .pdata_size = sizeof(timberdale_video_platform_data), - }, - { - .name = "timb-radio", - .num_resources = ARRAY_SIZE(timberdale_radio_resources), - .resources = timberdale_radio_resources, - .platform_data = &timberdale_radio_platform_data, - .pdata_size = sizeof(timberdale_radio_platform_data), - }, - { - .name = "xilinx_spi", - .num_resources = ARRAY_SIZE(timberdale_spi_resources), - .resources = timberdale_spi_resources, - .platform_data = &timberdale_xspi_platform_data, - .pdata_size = sizeof(timberdale_xspi_platform_data), - }, - { - .name = "ks8842", - .num_resources = ARRAY_SIZE(timberdale_eth_resources), - .resources = timberdale_eth_resources, - .platform_data = &timberdale_ks8842_platform_data, - .pdata_size = sizeof(timberdale_ks8842_platform_data), - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = { - { - .name = "timb-dma", - .num_resources = ARRAY_SIZE(timberdale_dma_resources), - .resources = timberdale_dma_resources, - .platform_data = &timb_dma_platform_data, - .pdata_size = sizeof(timb_dma_platform_data), - }, - { - .name = "timb-uart", - .num_resources = ARRAY_SIZE(timberdale_uart_resources), - .resources = timberdale_uart_resources, - }, - { - .name = "uartlite", - .num_resources = ARRAY_SIZE(timberdale_uartlite_resources), - .resources = timberdale_uartlite_resources, - }, - { - .name = "xiic-i2c", - .num_resources = ARRAY_SIZE(timberdale_xiic_resources), - .resources = timberdale_xiic_resources, - .platform_data = &timberdale_xiic_platform_data, - .pdata_size = sizeof(timberdale_xiic_platform_data), - }, - { - .name = "timb-gpio", - .num_resources = ARRAY_SIZE(timberdale_gpio_resources), - .resources = timberdale_gpio_resources, - .platform_data = &timberdale_gpio_platform_data, - .pdata_size = sizeof(timberdale_gpio_platform_data), - }, - { - .name = "timb-mlogicore", - .num_resources = ARRAY_SIZE(timberdale_mlogicore_resources), - .resources = timberdale_mlogicore_resources, - }, - { - .name = "timb-video", - .num_resources = ARRAY_SIZE(timberdale_video_resources), - .resources = timberdale_video_resources, - .platform_data = &timberdale_video_platform_data, - .pdata_size = sizeof(timberdale_video_platform_data), - }, - { - .name = "timb-radio", - .num_resources = ARRAY_SIZE(timberdale_radio_resources), - .resources = timberdale_radio_resources, - .platform_data = &timberdale_radio_platform_data, - .pdata_size = sizeof(timberdale_radio_platform_data), - }, - { - .name = "xilinx_spi", - .num_resources = ARRAY_SIZE(timberdale_spi_resources), - .resources = timberdale_spi_resources, - .platform_data = &timberdale_xspi_platform_data, - .pdata_size = sizeof(timberdale_xspi_platform_data), - }, - { - .name = "ks8842", - .num_resources = ARRAY_SIZE(timberdale_eth_resources), - .resources = timberdale_eth_resources, - .platform_data = &timberdale_ks8842_platform_data, - .pdata_size = sizeof(timberdale_ks8842_platform_data), - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = { - { - .name = "timb-dma", - .num_resources = ARRAY_SIZE(timberdale_dma_resources), - .resources = timberdale_dma_resources, - .platform_data = &timb_dma_platform_data, - .pdata_size = sizeof(timb_dma_platform_data), - }, - { - .name = "timb-uart", - .num_resources = ARRAY_SIZE(timberdale_uart_resources), - .resources = timberdale_uart_resources, - }, - { - .name = "xiic-i2c", - .num_resources = ARRAY_SIZE(timberdale_xiic_resources), - .resources = timberdale_xiic_resources, - .platform_data = &timberdale_xiic_platform_data, - .pdata_size = sizeof(timberdale_xiic_platform_data), - }, - { - .name = "timb-gpio", - .num_resources = ARRAY_SIZE(timberdale_gpio_resources), - .resources = timberdale_gpio_resources, - .platform_data = &timberdale_gpio_platform_data, - .pdata_size = sizeof(timberdale_gpio_platform_data), - }, - { - .name = "timb-video", - .num_resources = ARRAY_SIZE(timberdale_video_resources), - .resources = timberdale_video_resources, - .platform_data = &timberdale_video_platform_data, - .pdata_size = sizeof(timberdale_video_platform_data), - }, - { - .name = "timb-radio", - .num_resources = ARRAY_SIZE(timberdale_radio_resources), - .resources = timberdale_radio_resources, - .platform_data = &timberdale_radio_platform_data, - .pdata_size = sizeof(timberdale_radio_platform_data), - }, - { - .name = "xilinx_spi", - .num_resources = ARRAY_SIZE(timberdale_spi_resources), - .resources = timberdale_spi_resources, - .platform_data = &timberdale_xspi_platform_data, - .pdata_size = sizeof(timberdale_xspi_platform_data), - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = { - { - .name = "timb-dma", - .num_resources = ARRAY_SIZE(timberdale_dma_resources), - .resources = timberdale_dma_resources, - .platform_data = &timb_dma_platform_data, - .pdata_size = sizeof(timb_dma_platform_data), - }, - { - .name = "timb-uart", - .num_resources = ARRAY_SIZE(timberdale_uart_resources), - .resources = timberdale_uart_resources, - }, - { - .name = "ocores-i2c", - .num_resources = ARRAY_SIZE(timberdale_ocores_resources), - .resources = timberdale_ocores_resources, - .platform_data = &timberdale_ocores_platform_data, - .pdata_size = sizeof(timberdale_ocores_platform_data), - }, - { - .name = "timb-gpio", - .num_resources = ARRAY_SIZE(timberdale_gpio_resources), - .resources = timberdale_gpio_resources, - .platform_data = &timberdale_gpio_platform_data, - .pdata_size = sizeof(timberdale_gpio_platform_data), - }, - { - .name = "timb-video", - .num_resources = ARRAY_SIZE(timberdale_video_resources), - .resources = timberdale_video_resources, - .platform_data = &timberdale_video_platform_data, - .pdata_size = sizeof(timberdale_video_platform_data), - }, - { - .name = "timb-radio", - .num_resources = ARRAY_SIZE(timberdale_radio_resources), - .resources = timberdale_radio_resources, - .platform_data = &timberdale_radio_platform_data, - .pdata_size = sizeof(timberdale_radio_platform_data), - }, - { - .name = "xilinx_spi", - .num_resources = ARRAY_SIZE(timberdale_spi_resources), - .resources = timberdale_spi_resources, - .platform_data = &timberdale_xspi_platform_data, - .pdata_size = sizeof(timberdale_xspi_platform_data), - }, - { - .name = "ks8842", - .num_resources = ARRAY_SIZE(timberdale_eth_resources), - .resources = timberdale_eth_resources, - .platform_data = &timberdale_ks8842_platform_data, - .pdata_size = sizeof(timberdale_ks8842_platform_data), - }, -}; - -static const __devinitconst struct resource timberdale_sdhc_resources[] = { - /* located in bar 1 and bar 2 */ - { - .start = SDHC0OFFSET, - .end = SDHC0END, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TIMBERDALE_SDHC, - .end = IRQ_TIMBERDALE_SDHC, - .flags = IORESOURCE_IRQ, - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar1[] = { - { - .name = "sdhci", - .num_resources = ARRAY_SIZE(timberdale_sdhc_resources), - .resources = timberdale_sdhc_resources, - }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar2[] = { - { - .name = "sdhci", - .num_resources = ARRAY_SIZE(timberdale_sdhc_resources), - .resources = timberdale_sdhc_resources, - }, -}; - -static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct timberdale_device *priv = pci_get_drvdata(pdev); - - return sprintf(buf, "%d.%d.%d\n", priv->fw.major, priv->fw.minor, - priv->fw.config); -} - -static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); - -/*--------------------------------------------------------------------------*/ - -static int __devinit timb_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct timberdale_device *priv; - int err, i; - resource_size_t mapbase; - struct msix_entry *msix_entries = NULL; - u8 ip_setup; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - pci_set_drvdata(dev, priv); - - err = pci_enable_device(dev); - if (err) - goto err_enable; - - mapbase = pci_resource_start(dev, 0); - if (!mapbase) { - dev_err(&dev->dev, "No resource\n"); - goto err_start; - } - - /* create a resource for the PCI master register */ - priv->ctl_mapbase = mapbase + CHIPCTLOFFSET; - if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) { - dev_err(&dev->dev, "Failed to request ctl mem\n"); - goto err_request; - } - - priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE); - if (!priv->ctl_membase) { - dev_err(&dev->dev, "ioremap failed for ctl mem\n"); - goto err_ioremap; - } - - /* read the HW config */ - priv->fw.major = ioread32(priv->ctl_membase + TIMB_REV_MAJOR); - priv->fw.minor = ioread32(priv->ctl_membase + TIMB_REV_MINOR); - priv->fw.config = ioread32(priv->ctl_membase + TIMB_HW_CONFIG); - - if (priv->fw.major > TIMB_SUPPORTED_MAJOR) { - dev_err(&dev->dev, "The driver supports an older " - "version of the FPGA, please update the driver to " - "support %d.%d\n", priv->fw.major, priv->fw.minor); - goto err_config; - } - if (priv->fw.major < TIMB_SUPPORTED_MAJOR || - priv->fw.minor < TIMB_REQUIRED_MINOR) { - dev_err(&dev->dev, "The FPGA image is too old (%d.%d), " - "please upgrade the FPGA to at least: %d.%d\n", - priv->fw.major, priv->fw.minor, - TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR); - goto err_config; - } - - msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries), - GFP_KERNEL); - if (!msix_entries) - goto err_config; - - for (i = 0; i < TIMBERDALE_NR_IRQS; i++) - msix_entries[i].entry = i; - - err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS); - if (err) { - dev_err(&dev->dev, - "MSI-X init failed: %d, expected entries: %d\n", - err, TIMBERDALE_NR_IRQS); - goto err_msix; - } - - err = device_create_file(&dev->dev, &dev_attr_fw_ver); - if (err) - goto err_create_file; - - /* Reset all FPGA PLB peripherals */ - iowrite32(0x1, priv->ctl_membase + TIMB_SW_RST); - - /* update IRQ offsets in I2C board info */ - for (i = 0; i < ARRAY_SIZE(timberdale_i2c_board_info); i++) - timberdale_i2c_board_info[i].irq = - msix_entries[timberdale_i2c_board_info[i].irq].vector; - - /* Update the SPI configuration depending on the HW (8 or 16 bit) */ - if (priv->fw.config & TIMB_HW_CONFIG_SPI_8BIT) { - timberdale_xspi_platform_data.bits_per_word = 8; - timberdale_xspi_platform_data.devices = - timberdale_spi_8bit_board_info; - timberdale_xspi_platform_data.num_devices = - ARRAY_SIZE(timberdale_spi_8bit_board_info); - } else { - timberdale_xspi_platform_data.bits_per_word = 16; - timberdale_xspi_platform_data.devices = - timberdale_spi_16bit_board_info; - timberdale_xspi_platform_data.num_devices = - ARRAY_SIZE(timberdale_spi_16bit_board_info); - } - - ip_setup = priv->fw.config & TIMB_HW_VER_MASK; - switch (ip_setup) { - case TIMB_HW_VER0: - err = mfd_add_devices(&dev->dev, -1, - timberdale_cells_bar0_cfg0, - ARRAY_SIZE(timberdale_cells_bar0_cfg0), - &dev->resource[0], msix_entries[0].vector); - break; - case TIMB_HW_VER1: - err = mfd_add_devices(&dev->dev, -1, - timberdale_cells_bar0_cfg1, - ARRAY_SIZE(timberdale_cells_bar0_cfg1), - &dev->resource[0], msix_entries[0].vector); - break; - case TIMB_HW_VER2: - err = mfd_add_devices(&dev->dev, -1, - timberdale_cells_bar0_cfg2, - ARRAY_SIZE(timberdale_cells_bar0_cfg2), - &dev->resource[0], msix_entries[0].vector); - break; - case TIMB_HW_VER3: - err = mfd_add_devices(&dev->dev, -1, - timberdale_cells_bar0_cfg3, - ARRAY_SIZE(timberdale_cells_bar0_cfg3), - &dev->resource[0], msix_entries[0].vector); - break; - default: - dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", - priv->fw.major, priv->fw.minor, ip_setup); - err = -ENODEV; - goto err_mfd; - break; - } - - if (err) { - dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); - goto err_mfd; - } - - err = mfd_add_devices(&dev->dev, 0, - timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), - &dev->resource[1], msix_entries[0].vector); - if (err) { - dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); - goto err_mfd2; - } - - /* only version 0 and 3 have the iNand routed to SDHCI */ - if (((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER0) || - ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { - err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, - ARRAY_SIZE(timberdale_cells_bar2), - &dev->resource[2], msix_entries[0].vector); - if (err) { - dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); - goto err_mfd2; - } - } - - kfree(msix_entries); - - dev_info(&dev->dev, - "Found Timberdale Card. Rev: %d.%d, HW config: 0x%02x\n", - priv->fw.major, priv->fw.minor, priv->fw.config); - - return 0; - -err_mfd2: - mfd_remove_devices(&dev->dev); -err_mfd: - device_remove_file(&dev->dev, &dev_attr_fw_ver); -err_create_file: - pci_disable_msix(dev); -err_msix: - kfree(msix_entries); -err_config: - iounmap(priv->ctl_membase); -err_ioremap: - release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE); -err_request: - pci_set_drvdata(dev, NULL); -err_start: - pci_disable_device(dev); -err_enable: - kfree(priv); - pci_set_drvdata(dev, NULL); - return -ENODEV; -} - -static void __devexit timb_remove(struct pci_dev *dev) -{ - struct timberdale_device *priv = pci_get_drvdata(dev); - - mfd_remove_devices(&dev->dev); - - device_remove_file(&dev->dev, &dev_attr_fw_ver); - - iounmap(priv->ctl_membase); - release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE); - - pci_disable_msix(dev); - pci_disable_device(dev); - pci_set_drvdata(dev, NULL); - kfree(priv); -} - -static DEFINE_PCI_DEVICE_TABLE(timberdale_pci_tbl) = { - { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, timberdale_pci_tbl); - -static struct pci_driver timberdale_pci_driver = { - .name = DRIVER_NAME, - .id_table = timberdale_pci_tbl, - .probe = timb_probe, - .remove = __devexit_p(timb_remove), -}; - -static int __init timberdale_init(void) -{ - int err; - - err = pci_register_driver(&timberdale_pci_driver); - if (err < 0) { - printk(KERN_ERR - "Failed to register PCI driver for %s device.\n", - timberdale_pci_driver.name); - return -ENODEV; - } - - printk(KERN_INFO "Driver for %s has been successfully registered.\n", - timberdale_pci_driver.name); - - return 0; -} - -static void __exit timberdale_exit(void) -{ - pci_unregister_driver(&timberdale_pci_driver); - - printk(KERN_INFO "Driver for %s has been successfully unregistered.\n", - timberdale_pci_driver.name); -} - -module_init(timberdale_init); -module_exit(timberdale_exit); - -MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/timberdale.h b/ANDROID_3.4.5/drivers/mfd/timberdale.h deleted file mode 100644 index 4412acd8..00000000 --- a/ANDROID_3.4.5/drivers/mfd/timberdale.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * timberdale.h timberdale FPGA MFD driver defines - * Copyright (c) 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Supports: - * Timberdale FPGA - */ - -#ifndef MFD_TIMBERDALE_H -#define MFD_TIMBERDALE_H - -#define DRV_VERSION "0.3" - -/* This driver only support versions >= 3.8 and < 4.0 */ -#define TIMB_SUPPORTED_MAJOR 3 - -/* This driver only support minor >= 8 */ -#define TIMB_REQUIRED_MINOR 8 - -/* Registers of the control area */ -#define TIMB_REV_MAJOR 0x00 -#define TIMB_REV_MINOR 0x04 -#define TIMB_HW_CONFIG 0x08 -#define TIMB_SW_RST 0x40 - -/* bits in the TIMB_HW_CONFIG register */ -#define TIMB_HW_CONFIG_SPI_8BIT 0x80 - -#define TIMB_HW_VER_MASK 0x0f -#define TIMB_HW_VER0 0x00 -#define TIMB_HW_VER1 0x01 -#define TIMB_HW_VER2 0x02 -#define TIMB_HW_VER3 0x03 - -#define OCORESOFFSET 0x0 -#define OCORESEND 0x1f - -#define SPIOFFSET 0x80 -#define SPIEND 0xff - -#define UARTLITEOFFSET 0x100 -#define UARTLITEEND 0x10f - -#define RDSOFFSET 0x180 -#define RDSEND 0x183 - -#define ETHOFFSET 0x300 -#define ETHEND 0x3ff - -#define GPIOOFFSET 0x400 -#define GPIOEND 0x7ff - -#define CHIPCTLOFFSET 0x800 -#define CHIPCTLEND 0x8ff -#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET + 1) - -#define INTCOFFSET 0xc00 -#define INTCEND 0xfff -#define INTCSIZE (INTCEND - INTCOFFSET) - -#define MOSTOFFSET 0x1000 -#define MOSTEND 0x13ff - -#define UARTOFFSET 0x1400 -#define UARTEND 0x17ff - -#define XIICOFFSET 0x1800 -#define XIICEND 0x19ff - -#define I2SOFFSET 0x1C00 -#define I2SEND 0x1fff - -#define LOGIWOFFSET 0x30000 -#define LOGIWEND 0x37fff - -#define MLCOREOFFSET 0x40000 -#define MLCOREEND 0x43fff - -#define DMAOFFSET 0x01000000 -#define DMAEND 0x013fffff - -/* SDHC0 is placed in PCI bar 1 */ -#define SDHC0OFFSET 0x00 -#define SDHC0END 0xff - -/* SDHC1 is placed in PCI bar 2 */ -#define SDHC1OFFSET 0x00 -#define SDHC1END 0xff - -#define PCI_VENDOR_ID_TIMB 0x10ee -#define PCI_DEVICE_ID_TIMB 0xa123 - -#define IRQ_TIMBERDALE_INIC 0 -#define IRQ_TIMBERDALE_MLB 1 -#define IRQ_TIMBERDALE_GPIO 2 -#define IRQ_TIMBERDALE_I2C 3 -#define IRQ_TIMBERDALE_UART 4 -#define IRQ_TIMBERDALE_DMA 5 -#define IRQ_TIMBERDALE_I2S 6 -#define IRQ_TIMBERDALE_TSC_INT 7 -#define IRQ_TIMBERDALE_SDHC 8 -#define IRQ_TIMBERDALE_ADV7180 9 -#define IRQ_TIMBERDALE_ETHSW_IF 10 -#define IRQ_TIMBERDALE_SPI 11 -#define IRQ_TIMBERDALE_UARTLITE 12 -#define IRQ_TIMBERDALE_MLCORE 13 -#define IRQ_TIMBERDALE_MLCORE_BUF 14 -#define IRQ_TIMBERDALE_RDS 15 -#define TIMBERDALE_NR_IRQS 16 - -#define GPIO_PIN_ASCB 8 -#define GPIO_PIN_INIC_RST 14 -#define GPIO_PIN_BT_RST 15 -#define GPIO_NR_PINS 16 - -/* DMA Channels */ -#define DMA_UART_RX 0 -#define DMA_UART_TX 1 -#define DMA_MLB_RX 2 -#define DMA_MLB_TX 3 -#define DMA_VIDEO_RX 4 -#define DMA_VIDEO_DROP 5 -#define DMA_SDHCI_RX 6 -#define DMA_SDHCI_TX 7 -#define DMA_ETH_RX 8 -#define DMA_ETH_TX 9 - -#endif diff --git a/ANDROID_3.4.5/drivers/mfd/tmio_core.c b/ANDROID_3.4.5/drivers/mfd/tmio_core.c deleted file mode 100644 index 83af78c1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tmio_core.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright(c) 2009 Ian Molton <spyro@f2s.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/export.h> -#include <linux/mfd/tmio.h> - -int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base) -{ - /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf, shift, CNF_CMD, SDCREN); - sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); - - /* Disable SD power during suspend */ - sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01); - - /* The below is required but why? FIXME */ - sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f); - - /* Power down SD bus */ - sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00); - - return 0; -} -EXPORT_SYMBOL(tmio_core_mmc_enable); - -int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base) -{ - - /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf, shift, CNF_CMD, SDCREN); - sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); - - return 0; -} -EXPORT_SYMBOL(tmio_core_mmc_resume); - -void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state) -{ - sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00); -} -EXPORT_SYMBOL(tmio_core_mmc_pwr); - -void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state) -{ - sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0); -} -EXPORT_SYMBOL(tmio_core_mmc_clk_div); - diff --git a/ANDROID_3.4.5/drivers/mfd/tps6105x.c b/ANDROID_3.4.5/drivers/mfd/tps6105x.c deleted file mode 100644 index a293b978..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps6105x.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Core driver for TPS61050/61052 boost converters, used for while LED - * driving, audio power amplification, white LED flash, and generic - * boost conversion. Additionally it provides a 1-bit GPIO pin (out or in) - * and a flash synchronization pin to synchronize flash events when used as - * flashgun. - * - * Copyright (C) 2011 ST-Ericsson SA - * Written on behalf of Linaro for ST-Ericsson - * - * Author: Linus Walleij <linus.walleij@linaro.org> - * - * License terms: GNU General Public License (GPL) version 2 - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <linux/gpio.h> -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/regulator/driver.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps6105x.h> - -int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value) -{ - int ret; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value); - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(tps6105x_set); - -int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf) -{ - int ret; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_read_byte_data(tps6105x->client, reg); - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - *buf = ret; - return 0; -} -EXPORT_SYMBOL(tps6105x_get); - -/* - * Masks off the bits in the mask and sets the bits in the bitvalues - * parameter in one atomic operation - */ -int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, - u8 bitmask, u8 bitvalues) -{ - int ret; - u8 regval; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_read_byte_data(tps6105x->client, reg); - if (ret < 0) - goto fail; - regval = ret; - regval = (~bitmask & regval) | (bitmask & bitvalues); - ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval); -fail: - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(tps6105x_mask_and_set); - -static int __devinit tps6105x_startup(struct tps6105x *tps6105x) -{ - int ret; - u8 regval; - - ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); - if (ret) - return ret; - switch (regval >> TPS6105X_REG0_MODE_SHIFT) { - case TPS6105X_REG0_MODE_SHUTDOWN: - dev_info(&tps6105x->client->dev, - "TPS6105x found in SHUTDOWN mode\n"); - break; - case TPS6105X_REG0_MODE_TORCH: - dev_info(&tps6105x->client->dev, - "TPS6105x found in TORCH mode\n"); - break; - case TPS6105X_REG0_MODE_TORCH_FLASH: - dev_info(&tps6105x->client->dev, - "TPS6105x found in FLASH mode\n"); - break; - case TPS6105X_REG0_MODE_VOLTAGE: - dev_info(&tps6105x->client->dev, - "TPS6105x found in VOLTAGE mode\n"); - break; - default: - break; - } - - return ret; -} - -/* - * MFD cells - we have one cell which is selected operation - * mode, and we always have a GPIO cell. - */ -static struct mfd_cell tps6105x_cells[] = { - { - /* name will be runtime assigned */ - .id = -1, - }, - { - .name = "tps6105x-gpio", - .id = -1, - }, -}; - -static int __devinit tps6105x_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tps6105x *tps6105x; - struct tps6105x_platform_data *pdata; - int ret; - int i; - - tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL); - if (!tps6105x) - return -ENOMEM; - - i2c_set_clientdata(client, tps6105x); - tps6105x->client = client; - pdata = client->dev.platform_data; - tps6105x->pdata = pdata; - mutex_init(&tps6105x->lock); - - ret = tps6105x_startup(tps6105x); - if (ret) { - dev_err(&client->dev, "chip initialization failed\n"); - goto fail; - } - - /* Remove warning texts when you implement new cell drivers */ - switch (pdata->mode) { - case TPS6105X_MODE_SHUTDOWN: - dev_info(&client->dev, - "present, not used for anything, only GPIO\n"); - break; - case TPS6105X_MODE_TORCH: - tps6105x_cells[0].name = "tps6105x-leds"; - dev_warn(&client->dev, - "torch mode is unsupported\n"); - break; - case TPS6105X_MODE_TORCH_FLASH: - tps6105x_cells[0].name = "tps6105x-flash"; - dev_warn(&client->dev, - "flash mode is unsupported\n"); - break; - case TPS6105X_MODE_VOLTAGE: - tps6105x_cells[0].name ="tps6105x-regulator"; - break; - default: - break; - } - - /* Set up and register the platform devices. */ - for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) { - /* One state holder for all drivers, this is simple */ - tps6105x_cells[i].platform_data = tps6105x; - tps6105x_cells[i].pdata_size = sizeof(*tps6105x); - } - - ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, - ARRAY_SIZE(tps6105x_cells), NULL, 0); - if (ret) - goto fail; - - return 0; - -fail: - kfree(tps6105x); - return ret; -} - -static int __devexit tps6105x_remove(struct i2c_client *client) -{ - struct tps6105x *tps6105x = i2c_get_clientdata(client); - - mfd_remove_devices(&client->dev); - - /* Put chip in shutdown mode */ - tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, - TPS6105X_REG0_MODE_MASK, - TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); - - kfree(tps6105x); - return 0; -} - -static const struct i2c_device_id tps6105x_id[] = { - { "tps61050", 0 }, - { "tps61052", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tps6105x_id); - -static struct i2c_driver tps6105x_driver = { - .driver = { - .name = "tps6105x", - }, - .probe = tps6105x_probe, - .remove = __devexit_p(tps6105x_remove), - .id_table = tps6105x_id, -}; - -static int __init tps6105x_init(void) -{ - return i2c_add_driver(&tps6105x_driver); -} -subsys_initcall(tps6105x_init); - -static void __exit tps6105x_exit(void) -{ - i2c_del_driver(&tps6105x_driver); -} -module_exit(tps6105x_exit); - -MODULE_AUTHOR("Linus Walleij"); -MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65010.c b/ANDROID_3.4.5/drivers/mfd/tps65010.c deleted file mode 100644 index 93d5fdf0..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65010.c +++ /dev/null @@ -1,1098 +0,0 @@ -/* - * tps65010 - driver for tps6501x power management chips - * - * Copyright (C) 2004 Texas Instruments - * Copyright (C) 2004-2005 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/workqueue.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/mutex.h> -#include <linux/platform_device.h> - -#include <linux/i2c/tps65010.h> - -#include <linux/gpio.h> - - -/*-------------------------------------------------------------------------*/ - -#define DRIVER_VERSION "2 May 2005" -#define DRIVER_NAME (tps65010_driver.driver.name) - -MODULE_DESCRIPTION("TPS6501x Power Management Driver"); -MODULE_LICENSE("GPL"); - -static struct i2c_driver tps65010_driver; - -/*-------------------------------------------------------------------------*/ - -/* This driver handles a family of multipurpose chips, which incorporate - * voltage regulators, lithium ion/polymer battery charging, GPIOs, LEDs, - * and other features often needed in portable devices like cell phones - * or digital cameras. - * - * The tps65011 and tps65013 have different voltage settings compared - * to tps65010 and tps65012. The tps65013 has a NO_CHG status/irq. - * All except tps65010 have "wait" mode, possibly defaulted so that - * battery-insert != device-on. - * - * We could distinguish between some models by checking VDCDC1.UVLO or - * other registers, unless they've been changed already after powerup - * as part of board setup by a bootloader. - */ -enum tps_model { - TPS65010, - TPS65011, - TPS65012, - TPS65013, -}; - -struct tps65010 { - struct i2c_client *client; - struct mutex lock; - struct delayed_work work; - struct dentry *file; - unsigned charging:1; - unsigned por:1; - unsigned model:8; - u16 vbus; - unsigned long flags; -#define FLAG_VBUS_CHANGED 0 -#define FLAG_IRQ_ENABLE 1 - - /* copies of last register state */ - u8 chgstatus, regstatus, chgconf; - u8 nmask1, nmask2; - - u8 outmask; - struct gpio_chip chip; - struct platform_device *leds; -}; - -#define POWER_POLL_DELAY msecs_to_jiffies(5000) - -/*-------------------------------------------------------------------------*/ - -#if defined(DEBUG) || defined(CONFIG_DEBUG_FS) - -static void dbg_chgstat(char *buf, size_t len, u8 chgstatus) -{ - snprintf(buf, len, "%02x%s%s%s%s%s%s%s%s\n", - chgstatus, - (chgstatus & TPS_CHG_USB) ? " USB" : "", - (chgstatus & TPS_CHG_AC) ? " AC" : "", - (chgstatus & TPS_CHG_THERM) ? " therm" : "", - (chgstatus & TPS_CHG_TERM) ? " done" : - ((chgstatus & (TPS_CHG_USB|TPS_CHG_AC)) - ? " (charging)" : ""), - (chgstatus & TPS_CHG_TAPER_TMO) ? " taper_tmo" : "", - (chgstatus & TPS_CHG_CHG_TMO) ? " charge_tmo" : "", - (chgstatus & TPS_CHG_PRECHG_TMO) ? " prechg_tmo" : "", - (chgstatus & TPS_CHG_TEMP_ERR) ? " temp_err" : ""); -} - -static void dbg_regstat(char *buf, size_t len, u8 regstatus) -{ - snprintf(buf, len, "%02x %s%s%s%s%s%s%s%s\n", - regstatus, - (regstatus & TPS_REG_ONOFF) ? "off" : "(on)", - (regstatus & TPS_REG_COVER) ? " uncover" : "", - (regstatus & TPS_REG_UVLO) ? " UVLO" : "", - (regstatus & TPS_REG_NO_CHG) ? " NO_CHG" : "", - (regstatus & TPS_REG_PG_LD02) ? " ld02_bad" : "", - (regstatus & TPS_REG_PG_LD01) ? " ld01_bad" : "", - (regstatus & TPS_REG_PG_MAIN) ? " main_bad" : "", - (regstatus & TPS_REG_PG_CORE) ? " core_bad" : ""); -} - -static void dbg_chgconf(int por, char *buf, size_t len, u8 chgconfig) -{ - const char *hibit; - - if (por) - hibit = (chgconfig & TPS_CHARGE_POR) - ? "POR=69ms" : "POR=1sec"; - else - hibit = (chgconfig & TPS65013_AUA) ? "AUA" : ""; - - snprintf(buf, len, "%02x %s%s%s AC=%d%% USB=%dmA %sCharge\n", - chgconfig, hibit, - (chgconfig & TPS_CHARGE_RESET) ? " reset" : "", - (chgconfig & TPS_CHARGE_FAST) ? " fast" : "", - ({int p; switch ((chgconfig >> 3) & 3) { - case 3: p = 100; break; - case 2: p = 75; break; - case 1: p = 50; break; - default: p = 25; break; - }; p; }), - (chgconfig & TPS_VBUS_CHARGING) - ? ((chgconfig & TPS_VBUS_500MA) ? 500 : 100) - : 0, - (chgconfig & TPS_CHARGE_ENABLE) ? "" : "No"); -} - -#endif - -#ifdef DEBUG - -static void show_chgstatus(const char *label, u8 chgstatus) -{ - char buf [100]; - - dbg_chgstat(buf, sizeof buf, chgstatus); - pr_debug("%s: %s %s", DRIVER_NAME, label, buf); -} - -static void show_regstatus(const char *label, u8 regstatus) -{ - char buf [100]; - - dbg_regstat(buf, sizeof buf, regstatus); - pr_debug("%s: %s %s", DRIVER_NAME, label, buf); -} - -static void show_chgconfig(int por, const char *label, u8 chgconfig) -{ - char buf [100]; - - dbg_chgconf(por, buf, sizeof buf, chgconfig); - pr_debug("%s: %s %s", DRIVER_NAME, label, buf); -} - -#else - -static inline void show_chgstatus(const char *label, u8 chgstatus) { } -static inline void show_regstatus(const char *label, u8 chgstatus) { } -static inline void show_chgconfig(int por, const char *label, u8 chgconfig) { } - -#endif - -#ifdef CONFIG_DEBUG_FS - -static int dbg_show(struct seq_file *s, void *_) -{ - struct tps65010 *tps = s->private; - u8 value, v2; - unsigned i; - char buf[100]; - const char *chip; - - switch (tps->model) { - case TPS65010: chip = "tps65010"; break; - case TPS65011: chip = "tps65011"; break; - case TPS65012: chip = "tps65012"; break; - case TPS65013: chip = "tps65013"; break; - default: chip = NULL; break; - } - seq_printf(s, "driver %s\nversion %s\nchip %s\n\n", - DRIVER_NAME, DRIVER_VERSION, chip); - - mutex_lock(&tps->lock); - - /* FIXME how can we tell whether a battery is present? - * likely involves a charge gauging chip (like BQ26501). - */ - - seq_printf(s, "%scharging\n\n", tps->charging ? "" : "(not) "); - - - /* registers for monitoring battery charging and status; note - * that reading chgstat and regstat may ack IRQs... - */ - value = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG); - dbg_chgconf(tps->por, buf, sizeof buf, value); - seq_printf(s, "chgconfig %s", buf); - - value = i2c_smbus_read_byte_data(tps->client, TPS_CHGSTATUS); - dbg_chgstat(buf, sizeof buf, value); - seq_printf(s, "chgstat %s", buf); - value = i2c_smbus_read_byte_data(tps->client, TPS_MASK1); - dbg_chgstat(buf, sizeof buf, value); - seq_printf(s, "mask1 %s", buf); - /* ignore ackint1 */ - - value = i2c_smbus_read_byte_data(tps->client, TPS_REGSTATUS); - dbg_regstat(buf, sizeof buf, value); - seq_printf(s, "regstat %s", buf); - value = i2c_smbus_read_byte_data(tps->client, TPS_MASK2); - dbg_regstat(buf, sizeof buf, value); - seq_printf(s, "mask2 %s\n", buf); - /* ignore ackint2 */ - - schedule_delayed_work(&tps->work, POWER_POLL_DELAY); - - - /* VMAIN voltage, enable lowpower, etc */ - value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC1); - seq_printf(s, "vdcdc1 %02x\n", value); - - /* VCORE voltage, vibrator on/off */ - value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC2); - seq_printf(s, "vdcdc2 %02x\n", value); - - /* both LD0s, and their lowpower behavior */ - value = i2c_smbus_read_byte_data(tps->client, TPS_VREGS1); - seq_printf(s, "vregs1 %02x\n\n", value); - - - /* LEDs and GPIOs */ - value = i2c_smbus_read_byte_data(tps->client, TPS_LED1_ON); - v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED1_PER); - seq_printf(s, "led1 %s, on=%02x, per=%02x, %d/%d msec\n", - (value & 0x80) - ? ((v2 & 0x80) ? "on" : "off") - : ((v2 & 0x80) ? "blink" : "(nPG)"), - value, v2, - (value & 0x7f) * 10, (v2 & 0x7f) * 100); - - value = i2c_smbus_read_byte_data(tps->client, TPS_LED2_ON); - v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED2_PER); - seq_printf(s, "led2 %s, on=%02x, per=%02x, %d/%d msec\n", - (value & 0x80) - ? ((v2 & 0x80) ? "on" : "off") - : ((v2 & 0x80) ? "blink" : "off"), - value, v2, - (value & 0x7f) * 10, (v2 & 0x7f) * 100); - - value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO); - v2 = i2c_smbus_read_byte_data(tps->client, TPS_MASK3); - seq_printf(s, "defgpio %02x mask3 %02x\n", value, v2); - - for (i = 0; i < 4; i++) { - if (value & (1 << (4 + i))) - seq_printf(s, " gpio%d-out %s\n", i + 1, - (value & (1 << i)) ? "low" : "hi "); - else - seq_printf(s, " gpio%d-in %s %s %s\n", i + 1, - (value & (1 << i)) ? "hi " : "low", - (v2 & (1 << i)) ? "no-irq" : "irq", - (v2 & (1 << (4 + i))) ? "rising" : "falling"); - } - - mutex_unlock(&tps->lock); - return 0; -} - -static int dbg_tps_open(struct inode *inode, struct file *file) -{ - return single_open(file, dbg_show, inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = dbg_tps_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -#define DEBUG_FOPS &debug_fops - -#else -#define DEBUG_FOPS NULL -#endif - -/*-------------------------------------------------------------------------*/ - -/* handle IRQS in a task context, so we can use I2C calls */ -static void tps65010_interrupt(struct tps65010 *tps) -{ - u8 tmp = 0, mask, poll; - - /* IRQs won't trigger for certain events, but we can get - * others by polling (normally, with external power applied). - */ - poll = 0; - - /* regstatus irqs */ - if (tps->nmask2) { - tmp = i2c_smbus_read_byte_data(tps->client, TPS_REGSTATUS); - mask = tmp ^ tps->regstatus; - tps->regstatus = tmp; - mask &= tps->nmask2; - } else - mask = 0; - if (mask) { - tps->regstatus = tmp; - /* may need to shut something down ... */ - - /* "off" usually means deep sleep */ - if (tmp & TPS_REG_ONOFF) { - pr_info("%s: power off button\n", DRIVER_NAME); -#if 0 - /* REVISIT: this might need its own workqueue - * plus tweaks including deadlock avoidance ... - * also needs to get error handling and probably - * an #ifdef CONFIG_HIBERNATION - */ - hibernate(); -#endif - poll = 1; - } - } - - /* chgstatus irqs */ - if (tps->nmask1) { - tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGSTATUS); - mask = tmp ^ tps->chgstatus; - tps->chgstatus = tmp; - mask &= tps->nmask1; - } else - mask = 0; - if (mask) { - unsigned charging = 0; - - show_chgstatus("chg/irq", tmp); - if (tmp & (TPS_CHG_USB|TPS_CHG_AC)) - show_chgconfig(tps->por, "conf", tps->chgconf); - - /* Unless it was turned off or disabled, we charge any - * battery whenever there's power available for it - * and the charger hasn't been disabled. - */ - if (!(tps->chgstatus & ~(TPS_CHG_USB|TPS_CHG_AC)) - && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)) - && (tps->chgconf & TPS_CHARGE_ENABLE) - ) { - if (tps->chgstatus & TPS_CHG_USB) { - /* VBUS options are readonly until reconnect */ - if (mask & TPS_CHG_USB) - set_bit(FLAG_VBUS_CHANGED, &tps->flags); - charging = 1; - } else if (tps->chgstatus & TPS_CHG_AC) - charging = 1; - } - if (charging != tps->charging) { - tps->charging = charging; - pr_info("%s: battery %scharging\n", - DRIVER_NAME, charging ? "" : - ((tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)) - ? "NOT " : "dis")); - } - } - - /* always poll to detect (a) power removal, without tps65013 - * NO_CHG IRQ; or (b) restart of charging after stop. - */ - if ((tps->model != TPS65013 || !tps->charging) - && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))) - poll = 1; - if (poll) - schedule_delayed_work(&tps->work, POWER_POLL_DELAY); - - /* also potentially gpio-in rise or fall */ -} - -/* handle IRQs and polling using keventd for now */ -static void tps65010_work(struct work_struct *work) -{ - struct tps65010 *tps; - - tps = container_of(to_delayed_work(work), struct tps65010, work); - mutex_lock(&tps->lock); - - tps65010_interrupt(tps); - - if (test_and_clear_bit(FLAG_VBUS_CHANGED, &tps->flags)) { - int status; - u8 chgconfig, tmp; - - chgconfig = i2c_smbus_read_byte_data(tps->client, - TPS_CHGCONFIG); - chgconfig &= ~(TPS_VBUS_500MA | TPS_VBUS_CHARGING); - if (tps->vbus == 500) - chgconfig |= TPS_VBUS_500MA | TPS_VBUS_CHARGING; - else if (tps->vbus >= 100) - chgconfig |= TPS_VBUS_CHARGING; - - status = i2c_smbus_write_byte_data(tps->client, - TPS_CHGCONFIG, chgconfig); - - /* vbus update fails unless VBUS is connected! */ - tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG); - tps->chgconf = tmp; - show_chgconfig(tps->por, "update vbus", tmp); - } - - if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) - enable_irq(tps->client->irq); - - mutex_unlock(&tps->lock); -} - -static irqreturn_t tps65010_irq(int irq, void *_tps) -{ - struct tps65010 *tps = _tps; - - disable_irq_nosync(irq); - set_bit(FLAG_IRQ_ENABLE, &tps->flags); - schedule_delayed_work(&tps->work, 0); - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -/* offsets 0..3 == GPIO1..GPIO4 - * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes) - * offset 6 == vibrator motor driver - */ -static void -tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - if (offset < 4) - tps65010_set_gpio_out_value(offset + 1, value); - else if (offset < 6) - tps65010_set_led(offset - 3, value ? ON : OFF); - else - tps65010_set_vib(value); -} - -static int -tps65010_output(struct gpio_chip *chip, unsigned offset, int value) -{ - /* GPIOs may be input-only */ - if (offset < 4) { - struct tps65010 *tps; - - tps = container_of(chip, struct tps65010, chip); - if (!(tps->outmask & (1 << offset))) - return -EINVAL; - tps65010_set_gpio_out_value(offset + 1, value); - } else if (offset < 6) - tps65010_set_led(offset - 3, value ? ON : OFF); - else - tps65010_set_vib(value); - - return 0; -} - -static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - int value; - struct tps65010 *tps; - - tps = container_of(chip, struct tps65010, chip); - - if (offset < 4) { - value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO); - if (value < 0) - return 0; - if (value & (1 << (offset + 4))) /* output */ - return !(value & (1 << offset)); - else /* input */ - return (value & (1 << offset)); - } - - /* REVISIT we *could* report LED1/nPG and LED2 state ... */ - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static struct tps65010 *the_tps; - -static int __exit tps65010_remove(struct i2c_client *client) -{ - struct tps65010 *tps = i2c_get_clientdata(client); - struct tps65010_board *board = client->dev.platform_data; - - if (board && board->teardown) { - int status = board->teardown(client, board->context); - if (status < 0) - dev_dbg(&client->dev, "board %s %s err %d\n", - "teardown", client->name, status); - } - if (client->irq > 0) - free_irq(client->irq, tps); - cancel_delayed_work_sync(&tps->work); - debugfs_remove(tps->file); - kfree(tps); - the_tps = NULL; - return 0; -} - -static int tps65010_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tps65010 *tps; - int status; - struct tps65010_board *board = client->dev.platform_data; - - if (the_tps) { - dev_dbg(&client->dev, "only one tps6501x chip allowed\n"); - return -ENODEV; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -EINVAL; - - tps = kzalloc(sizeof *tps, GFP_KERNEL); - if (!tps) - return -ENOMEM; - - mutex_init(&tps->lock); - INIT_DELAYED_WORK(&tps->work, tps65010_work); - tps->client = client; - tps->model = id->driver_data; - - /* the IRQ is active low, but many gpio lines can't support that - * so this driver uses falling-edge triggers instead. - */ - if (client->irq > 0) { - status = request_irq(client->irq, tps65010_irq, - IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, - DRIVER_NAME, tps); - if (status < 0) { - dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", - client->irq, status); - goto fail1; - } - /* annoying race here, ideally we'd have an option - * to claim the irq now and enable it later. - * FIXME genirq IRQF_NOAUTOEN now solves that ... - */ - disable_irq(client->irq); - set_bit(FLAG_IRQ_ENABLE, &tps->flags); - } else - dev_warn(&client->dev, "IRQ not configured!\n"); - - - switch (tps->model) { - case TPS65010: - case TPS65012: - tps->por = 1; - break; - /* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */ - } - tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG); - show_chgconfig(tps->por, "conf/init", tps->chgconf); - - show_chgstatus("chg/init", - i2c_smbus_read_byte_data(client, TPS_CHGSTATUS)); - show_regstatus("reg/init", - i2c_smbus_read_byte_data(client, TPS_REGSTATUS)); - - pr_debug("%s: vdcdc1 0x%02x, vdcdc2 %02x, vregs1 %02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(client, TPS_VDCDC1), - i2c_smbus_read_byte_data(client, TPS_VDCDC2), - i2c_smbus_read_byte_data(client, TPS_VREGS1)); - pr_debug("%s: defgpio 0x%02x, mask3 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(client, TPS_DEFGPIO), - i2c_smbus_read_byte_data(client, TPS_MASK3)); - - i2c_set_clientdata(client, tps); - the_tps = tps; - -#if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG) - /* USB hosts can't draw VBUS. OTG devices could, later - * when OTG infrastructure enables it. USB peripherals - * could be relying on VBUS while booting, though. - */ - tps->vbus = 100; -#endif - - /* unmask the "interesting" irqs, then poll once to - * kickstart monitoring, initialize shadowed status - * registers, and maybe disable VBUS draw. - */ - tps->nmask1 = ~0; - (void) i2c_smbus_write_byte_data(client, TPS_MASK1, ~tps->nmask1); - - tps->nmask2 = TPS_REG_ONOFF; - if (tps->model == TPS65013) - tps->nmask2 |= TPS_REG_NO_CHG; - (void) i2c_smbus_write_byte_data(client, TPS_MASK2, ~tps->nmask2); - - (void) i2c_smbus_write_byte_data(client, TPS_MASK3, 0x0f - | i2c_smbus_read_byte_data(client, TPS_MASK3)); - - tps65010_work(&tps->work.work); - - tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, - tps, DEBUG_FOPS); - - /* optionally register GPIOs */ - if (board && board->base != 0) { - tps->outmask = board->outmask; - - tps->chip.label = client->name; - tps->chip.dev = &client->dev; - tps->chip.owner = THIS_MODULE; - - tps->chip.set = tps65010_gpio_set; - tps->chip.direction_output = tps65010_output; - - /* NOTE: only partial support for inputs; nyet IRQs */ - tps->chip.get = tps65010_gpio_get; - - tps->chip.base = board->base; - tps->chip.ngpio = 7; - tps->chip.can_sleep = 1; - - status = gpiochip_add(&tps->chip); - if (status < 0) - dev_err(&client->dev, "can't add gpiochip, err %d\n", - status); - else if (board->setup) { - status = board->setup(client, board->context); - if (status < 0) { - dev_dbg(&client->dev, - "board %s %s err %d\n", - "setup", client->name, status); - status = 0; - } - } - } - - return 0; -fail1: - kfree(tps); - return status; -} - -static const struct i2c_device_id tps65010_id[] = { - { "tps65010", TPS65010 }, - { "tps65011", TPS65011 }, - { "tps65012", TPS65012 }, - { "tps65013", TPS65013 }, - { "tps65014", TPS65011 }, /* tps65011 charging at 6.5V max */ - { } -}; -MODULE_DEVICE_TABLE(i2c, tps65010_id); - -static struct i2c_driver tps65010_driver = { - .driver = { - .name = "tps65010", - }, - .probe = tps65010_probe, - .remove = __exit_p(tps65010_remove), - .id_table = tps65010_id, -}; - -/*-------------------------------------------------------------------------*/ - -/* Draw from VBUS: - * 0 mA -- DON'T DRAW (might supply power instead) - * 100 mA -- usb unit load (slowest charge rate) - * 500 mA -- usb high power (fast battery charge) - */ -int tps65010_set_vbus_draw(unsigned mA) -{ - unsigned long flags; - - if (!the_tps) - return -ENODEV; - - /* assumes non-SMP */ - local_irq_save(flags); - if (mA >= 500) - mA = 500; - else if (mA >= 100) - mA = 100; - else - mA = 0; - the_tps->vbus = mA; - if ((the_tps->chgstatus & TPS_CHG_USB) - && test_and_set_bit( - FLAG_VBUS_CHANGED, &the_tps->flags)) { - /* gadget drivers call this in_irq() */ - schedule_delayed_work(&the_tps->work, 0); - } - local_irq_restore(flags); - - return 0; -} -EXPORT_SYMBOL(tps65010_set_vbus_draw); - -/*-------------------------------------------------------------------------*/ -/* tps65010_set_gpio_out_value parameter: - * gpio: GPIO1, GPIO2, GPIO3 or GPIO4 - * value: LOW or HIGH - */ -int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) -{ - int status; - unsigned defgpio; - - if (!the_tps) - return -ENODEV; - if ((gpio < GPIO1) || (gpio > GPIO4)) - return -EINVAL; - - mutex_lock(&the_tps->lock); - - defgpio = i2c_smbus_read_byte_data(the_tps->client, TPS_DEFGPIO); - - /* Configure GPIO for output */ - defgpio |= 1 << (gpio + 3); - - /* Writing 1 forces a logic 0 on that GPIO and vice versa */ - switch (value) { - case LOW: - defgpio |= 1 << (gpio - 1); /* set GPIO low by writing 1 */ - break; - /* case HIGH: */ - default: - defgpio &= ~(1 << (gpio - 1)); /* set GPIO high by writing 0 */ - break; - } - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_DEFGPIO, defgpio); - - pr_debug("%s: gpio%dout = %s, defgpio 0x%02x\n", DRIVER_NAME, - gpio, value ? "high" : "low", - i2c_smbus_read_byte_data(the_tps->client, TPS_DEFGPIO)); - - mutex_unlock(&the_tps->lock); - return status; -} -EXPORT_SYMBOL(tps65010_set_gpio_out_value); - -/*-------------------------------------------------------------------------*/ -/* tps65010_set_led parameter: - * led: LED1 or LED2 - * mode: ON, OFF or BLINK - */ -int tps65010_set_led(unsigned led, unsigned mode) -{ - int status; - unsigned led_on, led_per, offs; - - if (!the_tps) - return -ENODEV; - - if (led == LED1) - offs = 0; - else { - offs = 2; - led = LED2; - } - - mutex_lock(&the_tps->lock); - - pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led, - i2c_smbus_read_byte_data(the_tps->client, - TPS_LED1_ON + offs)); - - pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led, - i2c_smbus_read_byte_data(the_tps->client, - TPS_LED1_PER + offs)); - - switch (mode) { - case OFF: - led_on = 1 << 7; - led_per = 0 << 7; - break; - case ON: - led_on = 1 << 7; - led_per = 1 << 7; - break; - case BLINK: - led_on = 0x30 | (0 << 7); - led_per = 0x08 | (1 << 7); - break; - default: - printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n", - DRIVER_NAME); - mutex_unlock(&the_tps->lock); - return -EINVAL; - } - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_LED1_ON + offs, led_on); - - if (status != 0) { - printk(KERN_ERR "%s: Failed to write led%i_on register\n", - DRIVER_NAME, led); - mutex_unlock(&the_tps->lock); - return status; - } - - pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led, - i2c_smbus_read_byte_data(the_tps->client, TPS_LED1_ON + offs)); - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_LED1_PER + offs, led_per); - - if (status != 0) { - printk(KERN_ERR "%s: Failed to write led%i_per register\n", - DRIVER_NAME, led); - mutex_unlock(&the_tps->lock); - return status; - } - - pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led, - i2c_smbus_read_byte_data(the_tps->client, - TPS_LED1_PER + offs)); - - mutex_unlock(&the_tps->lock); - - return status; -} -EXPORT_SYMBOL(tps65010_set_led); - -/*-------------------------------------------------------------------------*/ -/* tps65010_set_vib parameter: - * value: ON or OFF - */ -int tps65010_set_vib(unsigned value) -{ - int status; - unsigned vdcdc2; - - if (!the_tps) - return -ENODEV; - - mutex_lock(&the_tps->lock); - - vdcdc2 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC2); - vdcdc2 &= ~(1 << 1); - if (value) - vdcdc2 |= (1 << 1); - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_VDCDC2, vdcdc2); - - pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off"); - - mutex_unlock(&the_tps->lock); - return status; -} -EXPORT_SYMBOL(tps65010_set_vib); - -/*-------------------------------------------------------------------------*/ -/* tps65010_set_low_pwr parameter: - * mode: ON or OFF - */ -int tps65010_set_low_pwr(unsigned mode) -{ - int status; - unsigned vdcdc1; - - if (!the_tps) - return -ENODEV; - - mutex_lock(&the_tps->lock); - - pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME, - mode ? "enable" : "disable", - i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1)); - - vdcdc1 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1); - - switch (mode) { - case OFF: - vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */ - break; - /* case ON: */ - default: - vdcdc1 |= TPS_ENABLE_LP; /* enable ENABLE_LP bit */ - break; - } - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_VDCDC1, vdcdc1); - - if (status != 0) - printk(KERN_ERR "%s: Failed to write vdcdc1 register\n", - DRIVER_NAME); - else - pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1)); - - mutex_unlock(&the_tps->lock); - - return status; -} -EXPORT_SYMBOL(tps65010_set_low_pwr); - -/*-------------------------------------------------------------------------*/ -/* tps65010_config_vregs1 parameter: - * value to be written to VREGS1 register - * Note: The complete register is written, set all bits you need - */ -int tps65010_config_vregs1(unsigned value) -{ - int status; - - if (!the_tps) - return -ENODEV; - - mutex_lock(&the_tps->lock); - - pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(the_tps->client, TPS_VREGS1)); - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_VREGS1, value); - - if (status != 0) - printk(KERN_ERR "%s: Failed to write vregs1 register\n", - DRIVER_NAME); - else - pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(the_tps->client, TPS_VREGS1)); - - mutex_unlock(&the_tps->lock); - - return status; -} -EXPORT_SYMBOL(tps65010_config_vregs1); - -int tps65010_config_vdcdc2(unsigned value) -{ - struct i2c_client *c; - int status; - - if (!the_tps) - return -ENODEV; - - c = the_tps->client; - mutex_lock(&the_tps->lock); - - pr_debug("%s: vdcdc2 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(c, TPS_VDCDC2)); - - status = i2c_smbus_write_byte_data(c, TPS_VDCDC2, value); - - if (status != 0) - printk(KERN_ERR "%s: Failed to write vdcdc2 register\n", - DRIVER_NAME); - else - pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(c, TPS_VDCDC2)); - - mutex_unlock(&the_tps->lock); - return status; -} -EXPORT_SYMBOL(tps65010_config_vdcdc2); - -/*-------------------------------------------------------------------------*/ -/* tps65013_set_low_pwr parameter: - * mode: ON or OFF - */ - -/* FIXME: Assumes AC or USB power is present. Setting AUA bit is not - required if power supply is through a battery */ - -int tps65013_set_low_pwr(unsigned mode) -{ - int status; - unsigned vdcdc1, chgconfig; - - if (!the_tps || the_tps->por) - return -ENODEV; - - mutex_lock(&the_tps->lock); - - pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n", - DRIVER_NAME, - mode ? "enable" : "disable", - i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG), - i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1)); - - chgconfig = i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG); - vdcdc1 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1); - - switch (mode) { - case OFF: - chgconfig &= ~TPS65013_AUA; /* disable AUA bit */ - vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */ - break; - /* case ON: */ - default: - chgconfig |= TPS65013_AUA; /* enable AUA bit */ - vdcdc1 |= TPS_ENABLE_LP; /* enable ENABLE_LP bit */ - break; - } - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_CHGCONFIG, chgconfig); - if (status != 0) { - printk(KERN_ERR "%s: Failed to write chconfig register\n", - DRIVER_NAME); - mutex_unlock(&the_tps->lock); - return status; - } - - chgconfig = i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG); - the_tps->chgconf = chgconfig; - show_chgconfig(0, "chgconf", chgconfig); - - status = i2c_smbus_write_byte_data(the_tps->client, - TPS_VDCDC1, vdcdc1); - - if (status != 0) - printk(KERN_ERR "%s: Failed to write vdcdc1 register\n", - DRIVER_NAME); - else - pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, - i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1)); - - mutex_unlock(&the_tps->lock); - - return status; -} -EXPORT_SYMBOL(tps65013_set_low_pwr); - -/*-------------------------------------------------------------------------*/ - -static int __init tps_init(void) -{ - u32 tries = 3; - int status = -ENODEV; - - printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION); - - /* some boards have startup glitches */ - while (tries--) { - status = i2c_add_driver(&tps65010_driver); - if (the_tps) - break; - i2c_del_driver(&tps65010_driver); - if (!tries) { - printk(KERN_ERR "%s: no chip?\n", DRIVER_NAME); - return -ENODEV; - } - pr_debug("%s: re-probe ...\n", DRIVER_NAME); - msleep(10); - } - - return status; -} -/* NOTE: this MUST be initialized before the other parts of the system - * that rely on it ... but after the i2c bus on which this relies. - * That is, much earlier than on PC-type systems, which don't often use - * I2C as a core system bus. - */ -subsys_initcall(tps_init); - -static void __exit tps_exit(void) -{ - i2c_del_driver(&tps65010_driver); -} -module_exit(tps_exit); - diff --git a/ANDROID_3.4.5/drivers/mfd/tps6507x.c b/ANDROID_3.4.5/drivers/mfd/tps6507x.c deleted file mode 100644 index 33ba7723..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps6507x.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * tps6507x.c -- TPS6507x chip family multi-function driver - * - * Copyright (c) 2010 RidgeRun (todd.fischer@ridgerun.com) - * - * Author: Todd Fischer - * todd.fischer@ridgerun.com - * - * Credits: - * - * Using code from wm831x-*.c, wm8400-core, Wolfson Microelectronics PLC. - * - * For licencing details see kernel-base/COPYING - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps6507x.h> - -static struct mfd_cell tps6507x_devs[] = { - { - .name = "tps6507x-pmic", - }, - { - .name = "tps6507x-ts", - }, -}; - - -static int tps6507x_i2c_read_device(struct tps6507x_dev *tps6507x, char reg, - int bytes, void *dest) -{ - struct i2c_client *i2c = tps6507x->i2c_client; - struct i2c_msg xfer[2]; - int ret; - - /* Write register */ - xfer[0].addr = i2c->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - - /* Read data */ - xfer[1].addr = i2c->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = bytes; - xfer[1].buf = dest; - - ret = i2c_transfer(i2c->adapter, xfer, 2); - if (ret == 2) - ret = 0; - else if (ret >= 0) - ret = -EIO; - - return ret; -} - -static int tps6507x_i2c_write_device(struct tps6507x_dev *tps6507x, char reg, - int bytes, void *src) -{ - struct i2c_client *i2c = tps6507x->i2c_client; - /* we add 1 byte for device register */ - u8 msg[TPS6507X_MAX_REGISTER + 1]; - int ret; - - if (bytes > TPS6507X_MAX_REGISTER) - return -EINVAL; - - msg[0] = reg; - memcpy(&msg[1], src, bytes); - - ret = i2c_master_send(i2c, msg, bytes + 1); - if (ret < 0) - return ret; - if (ret != bytes + 1) - return -EIO; - return 0; -} - -static int tps6507x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct tps6507x_dev *tps6507x; - int ret = 0; - - tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL); - if (tps6507x == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, tps6507x); - tps6507x->dev = &i2c->dev; - tps6507x->i2c_client = i2c; - tps6507x->read_dev = tps6507x_i2c_read_device; - tps6507x->write_dev = tps6507x_i2c_write_device; - - ret = mfd_add_devices(tps6507x->dev, -1, - tps6507x_devs, ARRAY_SIZE(tps6507x_devs), - NULL, 0); - - if (ret < 0) - goto err; - - return ret; - -err: - mfd_remove_devices(tps6507x->dev); - kfree(tps6507x); - return ret; -} - -static int tps6507x_i2c_remove(struct i2c_client *i2c) -{ - struct tps6507x_dev *tps6507x = i2c_get_clientdata(i2c); - - mfd_remove_devices(tps6507x->dev); - kfree(tps6507x); - - return 0; -} - -static const struct i2c_device_id tps6507x_i2c_id[] = { - { "tps6507x", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); - - -static struct i2c_driver tps6507x_i2c_driver = { - .driver = { - .name = "tps6507x", - .owner = THIS_MODULE, - }, - .probe = tps6507x_i2c_probe, - .remove = tps6507x_i2c_remove, - .id_table = tps6507x_i2c_id, -}; - -static int __init tps6507x_i2c_init(void) -{ - return i2c_add_driver(&tps6507x_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(tps6507x_i2c_init); - -static void __exit tps6507x_i2c_exit(void) -{ - i2c_del_driver(&tps6507x_i2c_driver); -} -module_exit(tps6507x_i2c_exit); - -MODULE_DESCRIPTION("TPS6507x chip family multi-function driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65090.c b/ANDROID_3.4.5/drivers/mfd/tps65090.c deleted file mode 100644 index a66d4df5..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65090.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Core driver for TI TPS65090 PMIC family - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - - * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps65090.h> -#include <linux/regmap.h> -#include <linux/err.h> - -#define NUM_INT_REG 2 -#define TOTAL_NUM_REG 0x18 - -/* interrupt status registers */ -#define TPS65090_INT_STS 0x0 -#define TPS65090_INT_STS2 0x1 - -/* interrupt mask registers */ -#define TPS65090_INT_MSK 0x2 -#define TPS65090_INT_MSK2 0x3 - -struct tps65090_irq_data { - u8 mask_reg; - u8 mask_pos; -}; - -#define TPS65090_IRQ(_reg, _mask_pos) \ - { \ - .mask_reg = (_reg), \ - .mask_pos = (_mask_pos), \ - } - -static const struct tps65090_irq_data tps65090_irqs[] = { - [0] = TPS65090_IRQ(0, 0), - [1] = TPS65090_IRQ(0, 1), - [2] = TPS65090_IRQ(0, 2), - [3] = TPS65090_IRQ(0, 3), - [4] = TPS65090_IRQ(0, 4), - [5] = TPS65090_IRQ(0, 5), - [6] = TPS65090_IRQ(0, 6), - [7] = TPS65090_IRQ(0, 7), - [8] = TPS65090_IRQ(1, 0), - [9] = TPS65090_IRQ(1, 1), - [10] = TPS65090_IRQ(1, 2), - [11] = TPS65090_IRQ(1, 3), - [12] = TPS65090_IRQ(1, 4), - [13] = TPS65090_IRQ(1, 5), - [14] = TPS65090_IRQ(1, 6), - [15] = TPS65090_IRQ(1, 7), -}; - -static struct mfd_cell tps65090s[] = { - { - .name = "tps65910-pmic", - }, - { - .name = "tps65910-regulator", - }, -}; - -struct tps65090 { - struct mutex lock; - struct device *dev; - struct i2c_client *client; - struct regmap *rmap; - struct irq_chip irq_chip; - struct mutex irq_lock; - int irq_base; - unsigned int id; -}; - -int tps65090_write(struct device *dev, int reg, uint8_t val) -{ - struct tps65090 *tps = dev_get_drvdata(dev); - return regmap_write(tps->rmap, reg, val); -} -EXPORT_SYMBOL_GPL(tps65090_write); - -int tps65090_read(struct device *dev, int reg, uint8_t *val) -{ - struct tps65090 *tps = dev_get_drvdata(dev); - unsigned int temp_val; - int ret; - ret = regmap_read(tps->rmap, reg, &temp_val); - if (!ret) - *val = temp_val; - return ret; -} -EXPORT_SYMBOL_GPL(tps65090_read); - -int tps65090_set_bits(struct device *dev, int reg, uint8_t bit_num) -{ - struct tps65090 *tps = dev_get_drvdata(dev); - return regmap_update_bits(tps->rmap, reg, BIT(bit_num), ~0u); -} -EXPORT_SYMBOL_GPL(tps65090_set_bits); - -int tps65090_clr_bits(struct device *dev, int reg, uint8_t bit_num) -{ - struct tps65090 *tps = dev_get_drvdata(dev); - return regmap_update_bits(tps->rmap, reg, BIT(bit_num), 0u); -} -EXPORT_SYMBOL_GPL(tps65090_clr_bits); - -static void tps65090_irq_lock(struct irq_data *data) -{ - struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data); - - mutex_lock(&tps65090->irq_lock); -} - -static void tps65090_irq_mask(struct irq_data *irq_data) -{ - struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->hwirq; - const struct tps65090_irq_data *data = &tps65090_irqs[__irq]; - - tps65090_set_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg), - data->mask_pos); -} - -static void tps65090_irq_unmask(struct irq_data *irq_data) -{ - struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - tps65090->irq_base; - const struct tps65090_irq_data *data = &tps65090_irqs[__irq]; - - tps65090_clr_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg), - data->mask_pos); -} - -static void tps65090_irq_sync_unlock(struct irq_data *data) -{ - struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data); - - mutex_unlock(&tps65090->irq_lock); -} - -static irqreturn_t tps65090_irq(int irq, void *data) -{ - struct tps65090 *tps65090 = data; - int ret = 0; - u8 status, mask; - unsigned long int acks = 0; - int i; - - for (i = 0; i < NUM_INT_REG; i++) { - ret = tps65090_read(tps65090->dev, TPS65090_INT_MSK + i, &mask); - if (ret < 0) { - dev_err(tps65090->dev, - "failed to read mask reg [addr:%d]\n", - TPS65090_INT_MSK + i); - return IRQ_NONE; - } - ret = tps65090_read(tps65090->dev, TPS65090_INT_STS + i, - &status); - if (ret < 0) { - dev_err(tps65090->dev, - "failed to read status reg [addr:%d]\n", - TPS65090_INT_STS + i); - return IRQ_NONE; - } - if (status) { - /* Ack only those interrupts which are not masked */ - status &= (~mask); - ret = tps65090_write(tps65090->dev, - TPS65090_INT_STS + i, status); - if (ret < 0) { - dev_err(tps65090->dev, - "failed to write interrupt status\n"); - return IRQ_NONE; - } - acks |= (status << (i * 8)); - } - } - - for_each_set_bit(i, &acks, ARRAY_SIZE(tps65090_irqs)) - handle_nested_irq(tps65090->irq_base + i); - return acks ? IRQ_HANDLED : IRQ_NONE; -} - -static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq, - int irq_base) -{ - int i, ret; - - if (!irq_base) { - dev_err(tps65090->dev, "IRQ base not set\n"); - return -EINVAL; - } - - mutex_init(&tps65090->irq_lock); - - for (i = 0; i < NUM_INT_REG; i++) - tps65090_write(tps65090->dev, TPS65090_INT_MSK + i, 0xFF); - - for (i = 0; i < NUM_INT_REG; i++) - tps65090_write(tps65090->dev, TPS65090_INT_STS + i, 0xff); - - tps65090->irq_base = irq_base; - tps65090->irq_chip.name = "tps65090"; - tps65090->irq_chip.irq_mask = tps65090_irq_mask; - tps65090->irq_chip.irq_unmask = tps65090_irq_unmask; - tps65090->irq_chip.irq_bus_lock = tps65090_irq_lock; - tps65090->irq_chip.irq_bus_sync_unlock = tps65090_irq_sync_unlock; - - for (i = 0; i < ARRAY_SIZE(tps65090_irqs); i++) { - int __irq = i + tps65090->irq_base; - irq_set_chip_data(__irq, tps65090); - irq_set_chip_and_handler(__irq, &tps65090->irq_chip, - handle_simple_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#endif - } - - ret = request_threaded_irq(irq, NULL, tps65090_irq, IRQF_ONESHOT, - "tps65090", tps65090); - if (!ret) { - device_init_wakeup(tps65090->dev, 1); - enable_irq_wake(irq); - } - - return ret; -} - -static bool is_volatile_reg(struct device *dev, unsigned int reg) -{ - if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS)) - return true; - else - return false; -} - -static const struct regmap_config tps65090_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = TOTAL_NUM_REG, - .num_reg_defaults_raw = TOTAL_NUM_REG, - .cache_type = REGCACHE_RBTREE, - .volatile_reg = is_volatile_reg, -}; - -static int __devinit tps65090_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tps65090_platform_data *pdata = client->dev.platform_data; - struct tps65090 *tps65090; - int ret; - - if (!pdata) { - dev_err(&client->dev, "tps65090 requires platform data\n"); - return -EINVAL; - } - - tps65090 = devm_kzalloc(&client->dev, sizeof(struct tps65090), - GFP_KERNEL); - if (tps65090 == NULL) - return -ENOMEM; - - tps65090->client = client; - tps65090->dev = &client->dev; - i2c_set_clientdata(client, tps65090); - - mutex_init(&tps65090->lock); - - if (client->irq) { - ret = tps65090_irq_init(tps65090, client->irq, pdata->irq_base); - if (ret) { - dev_err(&client->dev, "IRQ init failed with err: %d\n", - ret); - goto err_exit; - } - } - - tps65090->rmap = regmap_init_i2c(tps65090->client, - &tps65090_regmap_config); - if (IS_ERR(tps65090->rmap)) { - dev_err(&client->dev, "regmap_init failed with err: %ld\n", - PTR_ERR(tps65090->rmap)); - goto err_irq_exit; - }; - - ret = mfd_add_devices(tps65090->dev, -1, tps65090s, - ARRAY_SIZE(tps65090s), NULL, 0); - if (ret) { - dev_err(&client->dev, "add mfd devices failed with err: %d\n", - ret); - goto err_regmap_exit; - } - - return 0; - -err_regmap_exit: - regmap_exit(tps65090->rmap); - -err_irq_exit: - if (client->irq) - free_irq(client->irq, tps65090); -err_exit: - return ret; -} - -static int __devexit tps65090_i2c_remove(struct i2c_client *client) -{ - struct tps65090 *tps65090 = i2c_get_clientdata(client); - - mfd_remove_devices(tps65090->dev); - regmap_exit(tps65090->rmap); - if (client->irq) - free_irq(client->irq, tps65090); - - return 0; -} - -#ifdef CONFIG_PM -static int tps65090_i2c_suspend(struct i2c_client *client, pm_message_t state) -{ - if (client->irq) - disable_irq(client->irq); - return 0; -} - -static int tps65090_i2c_resume(struct i2c_client *client) -{ - if (client->irq) - enable_irq(client->irq); - return 0; -} -#endif - -static const struct i2c_device_id tps65090_id_table[] = { - { "tps65090", 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tps65090_id_table); - -static struct i2c_driver tps65090_driver = { - .driver = { - .name = "tps65090", - .owner = THIS_MODULE, - }, - .probe = tps65090_i2c_probe, - .remove = __devexit_p(tps65090_i2c_remove), -#ifdef CONFIG_PM - .suspend = tps65090_i2c_suspend, - .resume = tps65090_i2c_resume, -#endif - .id_table = tps65090_id_table, -}; - -static int __init tps65090_init(void) -{ - return i2c_add_driver(&tps65090_driver); -} -subsys_initcall(tps65090_init); - -static void __exit tps65090_exit(void) -{ - i2c_del_driver(&tps65090_driver); -} -module_exit(tps65090_exit); - -MODULE_DESCRIPTION("TPS65090 core driver"); -MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65217.c b/ANDROID_3.4.5/drivers/mfd/tps65217.c deleted file mode 100644 index f7d854e4..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65217.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * tps65217.c - * - * TPS65217 chip family multi-function driver - * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/regmap.h> -#include <linux/err.h> - -#include <linux/mfd/core.h> -#include <linux/mfd/tps65217.h> - -/** - * tps65217_reg_read: Read a single tps65217 register. - * - * @tps: Device to read from. - * @reg: Register to read. - * @val: Contians the value - */ -int tps65217_reg_read(struct tps65217 *tps, unsigned int reg, - unsigned int *val) -{ - return regmap_read(tps->regmap, reg, val); -} -EXPORT_SYMBOL_GPL(tps65217_reg_read); - -/** - * tps65217_reg_write: Write a single tps65217 register. - * - * @tps65217: Device to write to. - * @reg: Register to write to. - * @val: Value to write. - * @level: Password protected level - */ -int tps65217_reg_write(struct tps65217 *tps, unsigned int reg, - unsigned int val, unsigned int level) -{ - int ret; - unsigned int xor_reg_val; - - switch (level) { - case TPS65217_PROTECT_NONE: - return regmap_write(tps->regmap, reg, val); - case TPS65217_PROTECT_L1: - xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK; - ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD, - xor_reg_val); - if (ret < 0) - return ret; - - return regmap_write(tps->regmap, reg, val); - case TPS65217_PROTECT_L2: - xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK; - ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD, - xor_reg_val); - if (ret < 0) - return ret; - ret = regmap_write(tps->regmap, reg, val); - if (ret < 0) - return ret; - ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD, - xor_reg_val); - if (ret < 0) - return ret; - return regmap_write(tps->regmap, reg, val); - default: - return -EINVAL; - } -} -EXPORT_SYMBOL_GPL(tps65217_reg_write); - -/** - * tps65217_update_bits: Modify bits w.r.t mask, val and level. - * - * @tps65217: Device to write to. - * @reg: Register to read-write to. - * @mask: Mask. - * @val: Value to write. - * @level: Password protected level - */ -int tps65217_update_bits(struct tps65217 *tps, unsigned int reg, - unsigned int mask, unsigned int val, unsigned int level) -{ - int ret; - unsigned int data; - - ret = tps65217_reg_read(tps, reg, &data); - if (ret) { - dev_err(tps->dev, "Read from reg 0x%x failed\n", reg); - return ret; - } - - data &= ~mask; - data |= val & mask; - - ret = tps65217_reg_write(tps, reg, data, level); - if (ret) - dev_err(tps->dev, "Write for reg 0x%x failed\n", reg); - - return ret; -} - -int tps65217_set_bits(struct tps65217 *tps, unsigned int reg, - unsigned int mask, unsigned int val, unsigned int level) -{ - return tps65217_update_bits(tps, reg, mask, val, level); -} -EXPORT_SYMBOL_GPL(tps65217_set_bits); - -int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, - unsigned int mask, unsigned int level) -{ - return tps65217_update_bits(tps, reg, mask, 0, level); -} -EXPORT_SYMBOL_GPL(tps65217_clear_bits); - -static struct regmap_config tps65217_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -}; - -static int __devinit tps65217_probe(struct i2c_client *client, - const struct i2c_device_id *ids) -{ - struct tps65217 *tps; - struct tps65217_board *pdata = client->dev.platform_data; - int i, ret; - unsigned int version; - - tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); - if (!tps) - return -ENOMEM; - - tps->pdata = pdata; - tps->regmap = regmap_init_i2c(client, &tps65217_regmap_config); - if (IS_ERR(tps->regmap)) { - ret = PTR_ERR(tps->regmap); - dev_err(tps->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - i2c_set_clientdata(client, tps); - tps->dev = &client->dev; - - ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); - if (ret < 0) { - dev_err(tps->dev, "Failed to read revision" - " register: %d\n", ret); - goto err_regmap; - } - - dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n", - (version & TPS65217_CHIPID_CHIP_MASK) >> 4, - version & TPS65217_CHIPID_REV_MASK); - - for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { - struct platform_device *pdev; - - pdev = platform_device_alloc("tps65217-pmic", i); - if (!pdev) { - dev_err(tps->dev, "Cannot create regulator %d\n", i); - continue; - } - - pdev->dev.parent = tps->dev; - platform_device_add_data(pdev, &pdata->tps65217_init_data[i], - sizeof(pdata->tps65217_init_data[i])); - tps->regulator_pdev[i] = pdev; - - platform_device_add(pdev); - } - - return 0; - -err_regmap: - regmap_exit(tps->regmap); - - return ret; -} - -static int __devexit tps65217_remove(struct i2c_client *client) -{ - struct tps65217 *tps = i2c_get_clientdata(client); - int i; - - for (i = 0; i < TPS65217_NUM_REGULATOR; i++) - platform_device_unregister(tps->regulator_pdev[i]); - - regmap_exit(tps->regmap); - - return 0; -} - -static const struct i2c_device_id tps65217_id_table[] = { - {"tps65217", 0xF0}, - {/* end of list */} -}; -MODULE_DEVICE_TABLE(i2c, tps65217_id_table); - -static struct i2c_driver tps65217_driver = { - .driver = { - .name = "tps65217", - }, - .id_table = tps65217_id_table, - .probe = tps65217_probe, - .remove = __devexit_p(tps65217_remove), -}; - -static int __init tps65217_init(void) -{ - return i2c_add_driver(&tps65217_driver); -} -subsys_initcall(tps65217_init); - -static void __exit tps65217_exit(void) -{ - i2c_del_driver(&tps65217_driver); -} -module_exit(tps65217_exit); - -MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>"); -MODULE_DESCRIPTION("TPS65217 chip family multi-function driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps6586x.c b/ANDROID_3.4.5/drivers/mfd/tps6586x.c deleted file mode 100644 index a5ddf31b..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps6586x.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Core driver for TI TPS6586x PMIC family - * - * Copyright (c) 2010 CompuLab Ltd. - * Mike Rapoport <mike@compulab.co.il> - * - * Based on da903x.c. - * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport <mike@compulab.co.il> - * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao <eric.miao@marvell.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/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/i2c.h> - -#include <linux/mfd/core.h> -#include <linux/mfd/tps6586x.h> - -/* GPIO control registers */ -#define TPS6586X_GPIOSET1 0x5d -#define TPS6586X_GPIOSET2 0x5e - -/* interrupt control registers */ -#define TPS6586X_INT_ACK1 0xb5 -#define TPS6586X_INT_ACK2 0xb6 -#define TPS6586X_INT_ACK3 0xb7 -#define TPS6586X_INT_ACK4 0xb8 - -/* interrupt mask registers */ -#define TPS6586X_INT_MASK1 0xb0 -#define TPS6586X_INT_MASK2 0xb1 -#define TPS6586X_INT_MASK3 0xb2 -#define TPS6586X_INT_MASK4 0xb3 -#define TPS6586X_INT_MASK5 0xb4 - -/* device id */ -#define TPS6586X_VERSIONCRC 0xcd - -struct tps6586x_irq_data { - u8 mask_reg; - u8 mask_mask; -}; - -#define TPS6586X_IRQ(_reg, _mask) \ - { \ - .mask_reg = (_reg) - TPS6586X_INT_MASK1, \ - .mask_mask = (_mask), \ - } - -static const struct tps6586x_irq_data tps6586x_irqs[] = { - [TPS6586X_INT_PLDO_0] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 0), - [TPS6586X_INT_PLDO_1] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 1), - [TPS6586X_INT_PLDO_2] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 2), - [TPS6586X_INT_PLDO_3] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 3), - [TPS6586X_INT_PLDO_4] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 4), - [TPS6586X_INT_PLDO_5] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 5), - [TPS6586X_INT_PLDO_6] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 6), - [TPS6586X_INT_PLDO_7] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 7), - [TPS6586X_INT_COMP_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 0), - [TPS6586X_INT_ADC] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 1), - [TPS6586X_INT_PLDO_8] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 2), - [TPS6586X_INT_PLDO_9] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 3), - [TPS6586X_INT_PSM_0] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 4), - [TPS6586X_INT_PSM_1] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 5), - [TPS6586X_INT_PSM_2] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 6), - [TPS6586X_INT_PSM_3] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 7), - [TPS6586X_INT_RTC_ALM1] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 4), - [TPS6586X_INT_ACUSB_OVP] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 0x03), - [TPS6586X_INT_USB_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 2), - [TPS6586X_INT_AC_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 3), - [TPS6586X_INT_BAT_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 1 << 0), - [TPS6586X_INT_CHG_STAT] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 0xfc), - [TPS6586X_INT_CHG_TEMP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0x06), - [TPS6586X_INT_PP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0xf0), - [TPS6586X_INT_RESUME] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 5), - [TPS6586X_INT_LOW_SYS] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 6), - [TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1), -}; - -struct tps6586x { - struct mutex lock; - struct device *dev; - struct i2c_client *client; - - struct gpio_chip gpio; - struct irq_chip irq_chip; - struct mutex irq_lock; - int irq_base; - u32 irq_en; - u8 mask_cache[5]; - u8 mask_reg[5]; -}; - -static inline int __tps6586x_read(struct i2c_client *client, - int reg, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "failed reading at 0x%02x\n", reg); - return ret; - } - - *val = (uint8_t)ret; - - return 0; -} - -static inline int __tps6586x_reads(struct i2c_client *client, int reg, - int len, uint8_t *val) -{ - int ret; - - ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); - if (ret < 0) { - dev_err(&client->dev, "failed reading from 0x%02x\n", reg); - return ret; - } - - return 0; -} - -static inline int __tps6586x_write(struct i2c_client *client, - int reg, uint8_t val) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, val); - if (ret < 0) { - dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", - val, reg); - return ret; - } - - return 0; -} - -static inline int __tps6586x_writes(struct i2c_client *client, int reg, - int len, uint8_t *val) -{ - int ret, i; - - for (i = 0; i < len; i++) { - ret = __tps6586x_write(client, reg + i, *(val + i)); - if (ret < 0) - return ret; - } - - return 0; -} - -int tps6586x_write(struct device *dev, int reg, uint8_t val) -{ - return __tps6586x_write(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(tps6586x_write); - -int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val) -{ - return __tps6586x_writes(to_i2c_client(dev), reg, len, val); -} -EXPORT_SYMBOL_GPL(tps6586x_writes); - -int tps6586x_read(struct device *dev, int reg, uint8_t *val) -{ - return __tps6586x_read(to_i2c_client(dev), reg, val); -} -EXPORT_SYMBOL_GPL(tps6586x_read); - -int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val) -{ - return __tps6586x_reads(to_i2c_client(dev), reg, len, val); -} -EXPORT_SYMBOL_GPL(tps6586x_reads); - -int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct tps6586x *tps6586x = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&tps6586x->lock); - - ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); - if (ret) - goto out; - - if ((reg_val & bit_mask) != bit_mask) { - reg_val |= bit_mask; - ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); - } -out: - mutex_unlock(&tps6586x->lock); - return ret; -} -EXPORT_SYMBOL_GPL(tps6586x_set_bits); - -int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) -{ - struct tps6586x *tps6586x = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&tps6586x->lock); - - ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); - if (ret) - goto out; - - if (reg_val & bit_mask) { - reg_val &= ~bit_mask; - ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); - } -out: - mutex_unlock(&tps6586x->lock); - return ret; -} -EXPORT_SYMBOL_GPL(tps6586x_clr_bits); - -int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) -{ - struct tps6586x *tps6586x = dev_get_drvdata(dev); - uint8_t reg_val; - int ret = 0; - - mutex_lock(&tps6586x->lock); - - ret = __tps6586x_read(tps6586x->client, reg, ®_val); - if (ret) - goto out; - - if ((reg_val & mask) != val) { - reg_val = (reg_val & ~mask) | val; - ret = __tps6586x_write(tps6586x->client, reg, reg_val); - } -out: - mutex_unlock(&tps6586x->lock); - return ret; -} -EXPORT_SYMBOL_GPL(tps6586x_update); - -static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) -{ - struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio); - uint8_t val; - int ret; - - ret = __tps6586x_read(tps6586x->client, TPS6586X_GPIOSET2, &val); - if (ret) - return ret; - - return !!(val & (1 << offset)); -} - - -static void tps6586x_gpio_set(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct tps6586x *tps6586x = container_of(chip, struct tps6586x, gpio); - - tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET2, - value << offset, 1 << offset); -} - -static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, - int value) -{ - struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio); - uint8_t val, mask; - - tps6586x_gpio_set(gc, offset, value); - - val = 0x1 << (offset * 2); - mask = 0x3 << (offset * 2); - - return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask); -} - -static int tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) -{ - if (!gpio_base) - return 0; - - tps6586x->gpio.owner = THIS_MODULE; - tps6586x->gpio.label = tps6586x->client->name; - tps6586x->gpio.dev = tps6586x->dev; - tps6586x->gpio.base = gpio_base; - tps6586x->gpio.ngpio = 4; - tps6586x->gpio.can_sleep = 1; - - /* FIXME: add handling of GPIOs as dedicated inputs */ - tps6586x->gpio.direction_output = tps6586x_gpio_output; - tps6586x->gpio.set = tps6586x_gpio_set; - tps6586x->gpio.get = tps6586x_gpio_get; - - return gpiochip_add(&tps6586x->gpio); -} - -static int __remove_subdev(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - -static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) -{ - return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); -} - -static void tps6586x_irq_lock(struct irq_data *data) -{ - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); - - mutex_lock(&tps6586x->irq_lock); -} - -static void tps6586x_irq_enable(struct irq_data *irq_data) -{ - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - tps6586x->irq_base; - const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; - - tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; - tps6586x->irq_en |= (1 << __irq); -} - -static void tps6586x_irq_disable(struct irq_data *irq_data) -{ - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); - - unsigned int __irq = irq_data->irq - tps6586x->irq_base; - const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; - - tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; - tps6586x->irq_en &= ~(1 << __irq); -} - -static void tps6586x_irq_sync_unlock(struct irq_data *data) -{ - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { - if (tps6586x->mask_reg[i] != tps6586x->mask_cache[i]) { - if (!WARN_ON(tps6586x_write(tps6586x->dev, - TPS6586X_INT_MASK1 + i, - tps6586x->mask_reg[i]))) - tps6586x->mask_cache[i] = tps6586x->mask_reg[i]; - } - } - - mutex_unlock(&tps6586x->irq_lock); -} - -static irqreturn_t tps6586x_irq(int irq, void *data) -{ - struct tps6586x *tps6586x = data; - u32 acks; - int ret = 0; - - ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, - sizeof(acks), (uint8_t *)&acks); - - if (ret < 0) { - dev_err(tps6586x->dev, "failed to read interrupt status\n"); - return IRQ_NONE; - } - - acks = le32_to_cpu(acks); - - while (acks) { - int i = __ffs(acks); - - if (tps6586x->irq_en & (1 << i)) - handle_nested_irq(tps6586x->irq_base + i); - - acks &= ~(1 << i); - } - - return IRQ_HANDLED; -} - -static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, - int irq_base) -{ - int i, ret; - u8 tmp[4]; - - if (!irq_base) { - dev_warn(tps6586x->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } - - mutex_init(&tps6586x->irq_lock); - for (i = 0; i < 5; i++) { - tps6586x->mask_cache[i] = 0xff; - tps6586x->mask_reg[i] = 0xff; - tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff); - } - - tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp); - - tps6586x->irq_base = irq_base; - - tps6586x->irq_chip.name = "tps6586x"; - tps6586x->irq_chip.irq_enable = tps6586x_irq_enable; - tps6586x->irq_chip.irq_disable = tps6586x_irq_disable; - tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock; - tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock; - - for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { - int __irq = i + tps6586x->irq_base; - irq_set_chip_data(__irq, tps6586x); - irq_set_chip_and_handler(__irq, &tps6586x->irq_chip, - handle_simple_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#endif - } - - ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT, - "tps6586x", tps6586x); - - if (!ret) { - device_init_wakeup(tps6586x->dev, 1); - enable_irq_wake(irq); - } - - return ret; -} - -static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, - struct tps6586x_platform_data *pdata) -{ - struct tps6586x_subdev_info *subdev; - struct platform_device *pdev; - int i, ret = 0; - - for (i = 0; i < pdata->num_subdevs; i++) { - subdev = &pdata->subdevs[i]; - - pdev = platform_device_alloc(subdev->name, subdev->id); - if (!pdev) { - ret = -ENOMEM; - goto failed; - } - - pdev->dev.parent = tps6586x->dev; - pdev->dev.platform_data = subdev->platform_data; - - ret = platform_device_add(pdev); - if (ret) { - platform_device_put(pdev); - goto failed; - } - } - return 0; - -failed: - tps6586x_remove_subdevs(tps6586x); - return ret; -} - -static int __devinit tps6586x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tps6586x_platform_data *pdata = client->dev.platform_data; - struct tps6586x *tps6586x; - int ret; - - if (!pdata) { - dev_err(&client->dev, "tps6586x requires platform data\n"); - return -ENOTSUPP; - } - - ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC); - if (ret < 0) { - dev_err(&client->dev, "Chip ID read failed: %d\n", ret); - return -EIO; - } - - dev_info(&client->dev, "VERSIONCRC is %02x\n", ret); - - tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); - if (tps6586x == NULL) - return -ENOMEM; - - tps6586x->client = client; - tps6586x->dev = &client->dev; - i2c_set_clientdata(client, tps6586x); - - mutex_init(&tps6586x->lock); - - if (client->irq) { - ret = tps6586x_irq_init(tps6586x, client->irq, - pdata->irq_base); - if (ret) { - dev_err(&client->dev, "IRQ init failed: %d\n", ret); - goto err_irq_init; - } - } - - ret = tps6586x_gpio_init(tps6586x, pdata->gpio_base); - if (ret) { - dev_err(&client->dev, "GPIO registration failed: %d\n", ret); - goto err_gpio_init; - } - - ret = tps6586x_add_subdevs(tps6586x, pdata); - if (ret) { - dev_err(&client->dev, "add devices failed: %d\n", ret); - goto err_add_devs; - } - - return 0; - -err_add_devs: - if (pdata->gpio_base) { - ret = gpiochip_remove(&tps6586x->gpio); - if (ret) - dev_err(&client->dev, "Can't remove gpio chip: %d\n", - ret); - } -err_gpio_init: - if (client->irq) - free_irq(client->irq, tps6586x); -err_irq_init: - kfree(tps6586x); - return ret; -} - -static int __devexit tps6586x_i2c_remove(struct i2c_client *client) -{ - struct tps6586x *tps6586x = i2c_get_clientdata(client); - struct tps6586x_platform_data *pdata = client->dev.platform_data; - int ret; - - if (client->irq) - free_irq(client->irq, tps6586x); - - if (pdata->gpio_base) { - ret = gpiochip_remove(&tps6586x->gpio); - if (ret) - dev_err(&client->dev, "Can't remove gpio chip: %d\n", - ret); - } - - tps6586x_remove_subdevs(tps6586x); - kfree(tps6586x); - return 0; -} - -static const struct i2c_device_id tps6586x_id_table[] = { - { "tps6586x", 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tps6586x_id_table); - -static struct i2c_driver tps6586x_driver = { - .driver = { - .name = "tps6586x", - .owner = THIS_MODULE, - }, - .probe = tps6586x_i2c_probe, - .remove = __devexit_p(tps6586x_i2c_remove), - .id_table = tps6586x_id_table, -}; - -static int __init tps6586x_init(void) -{ - return i2c_add_driver(&tps6586x_driver); -} -subsys_initcall(tps6586x_init); - -static void __exit tps6586x_exit(void) -{ - i2c_del_driver(&tps6586x_driver); -} -module_exit(tps6586x_exit); - -MODULE_DESCRIPTION("TPS6586X core driver"); -MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65910-irq.c b/ANDROID_3.4.5/drivers/mfd/tps65910-irq.c deleted file mode 100644 index c9ed5c00..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65910-irq.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * tps65910-irq.c -- TI TPS6591x - * - * Copyright 2010 Texas Instruments Inc. - * - * Author: Graeme Gregory <gg@slimlogic.co.uk> - * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/bug.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/mfd/tps65910.h> - -static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, - int irq) -{ - return (irq - tps65910->irq_base); -} - -/* - * This is a threaded IRQ handler so can access I2C/SPI. Since all - * interrupts are clear on read the IRQ line will be reasserted and - * the physical IRQ will be handled again if another interrupt is - * asserted while we run - in the normal course of events this is a - * rare occurrence so we save I2C/SPI reads. We're also assuming that - * it's rare to get lots of interrupts firing simultaneously so try to - * minimise I/O. - */ -static irqreturn_t tps65910_irq(int irq, void *irq_data) -{ - struct tps65910 *tps65910 = irq_data; - u32 irq_sts; - u32 irq_mask; - u8 reg; - int i; - - tps65910->read(tps65910, TPS65910_INT_STS, 1, ®); - irq_sts = reg; - tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®); - irq_sts |= reg << 8; - switch (tps65910_chip_id(tps65910)) { - case TPS65911: - tps65910->read(tps65910, TPS65910_INT_STS3, 1, ®); - irq_sts |= reg << 16; - } - - tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); - irq_mask = reg; - tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); - irq_mask |= reg << 8; - switch (tps65910_chip_id(tps65910)) { - case TPS65911: - tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); - irq_mask |= reg << 16; - } - - irq_sts &= ~irq_mask; - - if (!irq_sts) - return IRQ_NONE; - - for (i = 0; i < tps65910->irq_num; i++) { - - if (!(irq_sts & (1 << i))) - continue; - - handle_nested_irq(tps65910->irq_base + i); - } - - /* Write the STS register back to clear IRQs we handled */ - reg = irq_sts & 0xFF; - irq_sts >>= 8; - tps65910->write(tps65910, TPS65910_INT_STS, 1, ®); - reg = irq_sts & 0xFF; - tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®); - switch (tps65910_chip_id(tps65910)) { - case TPS65911: - reg = irq_sts >> 8; - tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®); - } - - return IRQ_HANDLED; -} - -static void tps65910_irq_lock(struct irq_data *data) -{ - struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - - mutex_lock(&tps65910->irq_lock); -} - -static void tps65910_irq_sync_unlock(struct irq_data *data) -{ - struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - u32 reg_mask; - u8 reg; - - tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); - reg_mask = reg; - tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); - reg_mask |= reg << 8; - switch (tps65910_chip_id(tps65910)) { - case TPS65911: - tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); - reg_mask |= reg << 16; - } - - if (tps65910->irq_mask != reg_mask) { - reg = tps65910->irq_mask & 0xFF; - tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); - reg = tps65910->irq_mask >> 8 & 0xFF; - tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); - switch (tps65910_chip_id(tps65910)) { - case TPS65911: - reg = tps65910->irq_mask >> 16; - tps65910->write(tps65910, TPS65910_INT_MSK3, 1, ®); - } - } - mutex_unlock(&tps65910->irq_lock); -} - -static void tps65910_irq_enable(struct irq_data *data) -{ - struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - - tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq)); -} - -static void tps65910_irq_disable(struct irq_data *data) -{ - struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - - tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq)); -} - -#ifdef CONFIG_PM_SLEEP -static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable) -{ - struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - return irq_set_irq_wake(tps65910->chip_irq, enable); -} -#else -#define tps65910_irq_set_wake NULL -#endif - -static struct irq_chip tps65910_irq_chip = { - .name = "tps65910", - .irq_bus_lock = tps65910_irq_lock, - .irq_bus_sync_unlock = tps65910_irq_sync_unlock, - .irq_disable = tps65910_irq_disable, - .irq_enable = tps65910_irq_enable, - .irq_set_wake = tps65910_irq_set_wake, -}; - -int tps65910_irq_init(struct tps65910 *tps65910, int irq, - struct tps65910_platform_data *pdata) -{ - int ret, cur_irq; - int flags = IRQF_ONESHOT; - - if (!irq) { - dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n"); - return -EINVAL; - } - - if (!pdata || !pdata->irq_base) { - dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n"); - return -EINVAL; - } - - tps65910->irq_mask = 0xFFFFFF; - - mutex_init(&tps65910->irq_lock); - tps65910->chip_irq = irq; - tps65910->irq_base = pdata->irq_base; - - switch (tps65910_chip_id(tps65910)) { - case TPS65910: - tps65910->irq_num = TPS65910_NUM_IRQ; - break; - case TPS65911: - tps65910->irq_num = TPS65911_NUM_IRQ; - break; - } - - /* Register with genirq */ - for (cur_irq = tps65910->irq_base; - cur_irq < tps65910->irq_num + tps65910->irq_base; - cur_irq++) { - irq_set_chip_data(cur_irq, tps65910); - irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); - - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, - "tps65910", tps65910); - - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); - - if (ret != 0) - dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret); - - return ret; -} - -int tps65910_irq_exit(struct tps65910 *tps65910) -{ - if (tps65910->chip_irq) - free_irq(tps65910->chip_irq, tps65910); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/tps65910.c b/ANDROID_3.4.5/drivers/mfd/tps65910.c deleted file mode 100644 index bf2b25eb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65910.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * tps65910.c -- TI TPS6591x - * - * Copyright 2010 Texas Instruments Inc. - * - * Author: Graeme Gregory <gg@slimlogic.co.uk> - * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/gpio.h> -#include <linux/mfd/core.h> -#include <linux/regmap.h> -#include <linux/mfd/tps65910.h> - -static struct mfd_cell tps65910s[] = { - { - .name = "tps65910-pmic", - }, - { - .name = "tps65910-rtc", - }, - { - .name = "tps65910-power", - }, -}; - - -static int tps65910_i2c_read(struct tps65910 *tps65910, u8 reg, - int bytes, void *dest) -{ - return regmap_bulk_read(tps65910->regmap, reg, dest, bytes); -} - -static int tps65910_i2c_write(struct tps65910 *tps65910, u8 reg, - int bytes, void *src) -{ - return regmap_bulk_write(tps65910->regmap, reg, src, bytes); -} - -int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask) -{ - return regmap_update_bits(tps65910->regmap, reg, mask, mask); -} -EXPORT_SYMBOL_GPL(tps65910_set_bits); - -int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask) -{ - return regmap_update_bits(tps65910->regmap, reg, mask, 0); -} -EXPORT_SYMBOL_GPL(tps65910_clear_bits); - -static bool is_volatile_reg(struct device *dev, unsigned int reg) -{ - struct tps65910 *tps65910 = dev_get_drvdata(dev); - - /* - * Caching all regulator registers. - * All regualator register address range is same for - * TPS65910 and TPS65911 - */ - if ((reg >= TPS65910_VIO) && (reg <= TPS65910_VDAC)) { - /* Check for non-existing register */ - if (tps65910_chip_id(tps65910) == TPS65910) - if ((reg == TPS65911_VDDCTRL_OP) || - (reg == TPS65911_VDDCTRL_SR)) - return true; - return false; - } - return true; -} - -static const struct regmap_config tps65910_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .volatile_reg = is_volatile_reg, - .max_register = TPS65910_MAX_REGISTER, - .num_reg_defaults_raw = TPS65910_MAX_REGISTER, - .cache_type = REGCACHE_RBTREE, -}; - -static int tps65910_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct tps65910 *tps65910; - struct tps65910_board *pmic_plat_data; - struct tps65910_platform_data *init_data; - int ret = 0; - - pmic_plat_data = dev_get_platdata(&i2c->dev); - if (!pmic_plat_data) - return -EINVAL; - - init_data = kzalloc(sizeof(struct tps65910_platform_data), GFP_KERNEL); - if (init_data == NULL) - return -ENOMEM; - - tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL); - if (tps65910 == NULL) { - kfree(init_data); - return -ENOMEM; - } - - i2c_set_clientdata(i2c, tps65910); - tps65910->dev = &i2c->dev; - tps65910->i2c_client = i2c; - tps65910->id = id->driver_data; - tps65910->read = tps65910_i2c_read; - tps65910->write = tps65910_i2c_write; - mutex_init(&tps65910->io_mutex); - - tps65910->regmap = regmap_init_i2c(i2c, &tps65910_regmap_config); - if (IS_ERR(tps65910->regmap)) { - ret = PTR_ERR(tps65910->regmap); - dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); - goto regmap_err; - } - - ret = mfd_add_devices(tps65910->dev, -1, - tps65910s, ARRAY_SIZE(tps65910s), - NULL, 0); - if (ret < 0) - goto err; - - init_data->irq = pmic_plat_data->irq; - init_data->irq_base = pmic_plat_data->irq_base; - - tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); - - tps65910_irq_init(tps65910, init_data->irq, init_data); - - kfree(init_data); - return ret; - -err: - regmap_exit(tps65910->regmap); -regmap_err: - kfree(tps65910); - kfree(init_data); - return ret; -} - -static int tps65910_i2c_remove(struct i2c_client *i2c) -{ - struct tps65910 *tps65910 = i2c_get_clientdata(i2c); - - tps65910_irq_exit(tps65910); - mfd_remove_devices(tps65910->dev); - regmap_exit(tps65910->regmap); - kfree(tps65910); - - return 0; -} - -static const struct i2c_device_id tps65910_i2c_id[] = { - { "tps65910", TPS65910 }, - { "tps65911", TPS65911 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id); - - -static struct i2c_driver tps65910_i2c_driver = { - .driver = { - .name = "tps65910", - .owner = THIS_MODULE, - }, - .probe = tps65910_i2c_probe, - .remove = tps65910_i2c_remove, - .id_table = tps65910_i2c_id, -}; - -static int __init tps65910_i2c_init(void) -{ - return i2c_add_driver(&tps65910_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(tps65910_i2c_init); - -static void __exit tps65910_i2c_exit(void) -{ - i2c_del_driver(&tps65910_i2c_driver); -} -module_exit(tps65910_i2c_exit); - -MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); -MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>"); -MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65911-comparator.c b/ANDROID_3.4.5/drivers/mfd/tps65911-comparator.c deleted file mode 100644 index e7ff783a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65911-comparator.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * tps65910.c -- TI TPS6591x - * - * Copyright 2010 Texas Instruments Inc. - * - * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/platform_device.h> -#include <linux/debugfs.h> -#include <linux/gpio.h> -#include <linux/mfd/tps65910.h> - -#define COMP 0 -#define COMP1 1 -#define COMP2 2 - -/* Comparator 1 voltage selection table in milivolts */ -static const u16 COMP_VSEL_TABLE[] = { - 0, 2500, 2500, 2500, 2500, 2550, 2600, 2650, - 2700, 2750, 2800, 2850, 2900, 2950, 3000, 3050, - 3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450, - 3500, -}; - -struct comparator { - const char *name; - int reg; - int uV_max; - const u16 *vsel_table; -}; - -static struct comparator tps_comparators[] = { - { - .name = "COMP1", - .reg = TPS65911_VMBCH, - .uV_max = 3500, - .vsel_table = COMP_VSEL_TABLE, - }, - { - .name = "COMP2", - .reg = TPS65911_VMBCH2, - .uV_max = 3500, - .vsel_table = COMP_VSEL_TABLE, - }, -}; - -static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage) -{ - struct comparator tps_comp = tps_comparators[id]; - int curr_voltage = 0; - int ret; - u8 index = 0, val; - - if (id == COMP) - return 0; - - while (curr_voltage < tps_comp.uV_max) { - curr_voltage = tps_comp.vsel_table[index]; - if (curr_voltage >= voltage) - break; - else if (curr_voltage < voltage) - index ++; - } - - if (curr_voltage > tps_comp.uV_max) - return -EINVAL; - - val = index << 1; - ret = tps65910->write(tps65910, tps_comp.reg, 1, &val); - - return ret; -} - -static int comp_threshold_get(struct tps65910 *tps65910, int id) -{ - struct comparator tps_comp = tps_comparators[id]; - int ret; - u8 val; - - if (id == COMP) - return 0; - - ret = tps65910->read(tps65910, tps_comp.reg, 1, &val); - if (ret < 0) - return ret; - - val >>= 1; - return tps_comp.vsel_table[val]; -} - -static ssize_t comp_threshold_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tps65910 *tps65910 = dev_get_drvdata(dev->parent); - struct attribute comp_attr = attr->attr; - int id, uVolt; - - if (!strcmp(comp_attr.name, "comp1_threshold")) - id = COMP1; - else if (!strcmp(comp_attr.name, "comp2_threshold")) - id = COMP2; - else - return -EINVAL; - - uVolt = comp_threshold_get(tps65910, id); - - return sprintf(buf, "%d\n", uVolt); -} - -static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL); -static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL); - -static __devinit int tps65911_comparator_probe(struct platform_device *pdev) -{ - struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); - struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); - int ret; - - ret = comp_threshold_set(tps65910, COMP1, pdata->vmbch_threshold); - if (ret < 0) { - dev_err(&pdev->dev, "cannot set COMP1 threshold\n"); - return ret; - } - - ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold); - if (ret < 0) { - dev_err(&pdev->dev, "cannot set COMP2 theshold\n"); - return ret; - } - - /* Create sysfs entry */ - ret = device_create_file(&pdev->dev, &dev_attr_comp1_threshold); - if (ret < 0) - dev_err(&pdev->dev, "failed to add COMP1 sysfs file\n"); - - ret = device_create_file(&pdev->dev, &dev_attr_comp2_threshold); - if (ret < 0) - dev_err(&pdev->dev, "failed to add COMP2 sysfs file\n"); - - return ret; -} - -static __devexit int tps65911_comparator_remove(struct platform_device *pdev) -{ - struct tps65910 *tps65910; - - tps65910 = dev_get_drvdata(pdev->dev.parent); - device_remove_file(&pdev->dev, &dev_attr_comp2_threshold); - device_remove_file(&pdev->dev, &dev_attr_comp1_threshold); - - return 0; -} - -static struct platform_driver tps65911_comparator_driver = { - .driver = { - .name = "tps65911-comparator", - .owner = THIS_MODULE, - }, - .probe = tps65911_comparator_probe, - .remove = __devexit_p(tps65911_comparator_remove), -}; - -static int __init tps65911_comparator_init(void) -{ - return platform_driver_register(&tps65911_comparator_driver); -} -subsys_initcall(tps65911_comparator_init); - -static void __exit tps65911_comparator_exit(void) -{ - platform_driver_unregister(&tps65911_comparator_driver); -} -module_exit(tps65911_comparator_exit); - -MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>"); -MODULE_DESCRIPTION("TPS65911 comparator driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:tps65911-comparator"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65912-core.c b/ANDROID_3.4.5/drivers/mfd/tps65912-core.c deleted file mode 100644 index 74fd8cb5..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65912-core.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * tps65912-core.c -- TI TPS65912x - * - * Copyright 2011 Texas Instruments Inc. - * - * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This driver is based on wm8350 implementation. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps65912.h> - -static struct mfd_cell tps65912s[] = { - { - .name = "tps65912-pmic", - }, -}; - -int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask) -{ - u8 data; - int err; - - mutex_lock(&tps65912->io_mutex); - - err = tps65912->read(tps65912, reg, 1, &data); - if (err) { - dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); - goto out; - } - - data |= mask; - err = tps65912->write(tps65912, reg, 1, &data); - if (err) - dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); - -out: - mutex_unlock(&tps65912->io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(tps65912_set_bits); - -int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask) -{ - u8 data; - int err; - - mutex_lock(&tps65912->io_mutex); - err = tps65912->read(tps65912, reg, 1, &data); - if (err) { - dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); - goto out; - } - - data &= ~mask; - err = tps65912->write(tps65912, reg, 1, &data); - if (err) - dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); - -out: - mutex_unlock(&tps65912->io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(tps65912_clear_bits); - -static inline int tps65912_read(struct tps65912 *tps65912, u8 reg) -{ - u8 val; - int err; - - err = tps65912->read(tps65912, reg, 1, &val); - if (err < 0) - return err; - - return val; -} - -static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val) -{ - return tps65912->write(tps65912, reg, 1, &val); -} - -int tps65912_reg_read(struct tps65912 *tps65912, u8 reg) -{ - int data; - - mutex_lock(&tps65912->io_mutex); - - data = tps65912_read(tps65912, reg); - if (data < 0) - dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); - - mutex_unlock(&tps65912->io_mutex); - return data; -} -EXPORT_SYMBOL_GPL(tps65912_reg_read); - -int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val) -{ - int err; - - mutex_lock(&tps65912->io_mutex); - - err = tps65912_write(tps65912, reg, val); - if (err < 0) - dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg); - - mutex_unlock(&tps65912->io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(tps65912_reg_write); - -int tps65912_device_init(struct tps65912 *tps65912) -{ - struct tps65912_board *pmic_plat_data = tps65912->dev->platform_data; - struct tps65912_platform_data *init_data; - int ret, dcdc_avs, value; - - init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL); - if (init_data == NULL) - return -ENOMEM; - - mutex_init(&tps65912->io_mutex); - dev_set_drvdata(tps65912->dev, tps65912); - - dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 | - pmic_plat_data->is_dcdc2_avs << 1 | - pmic_plat_data->is_dcdc3_avs << 2 | - pmic_plat_data->is_dcdc4_avs << 3); - if (dcdc_avs) { - tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value); - dcdc_avs |= value; - tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs); - } - - ret = mfd_add_devices(tps65912->dev, -1, - tps65912s, ARRAY_SIZE(tps65912s), - NULL, 0); - if (ret < 0) - goto err; - - init_data->irq = pmic_plat_data->irq; - init_data->irq_base = pmic_plat_data->irq_base; - ret = tps65912_irq_init(tps65912, init_data->irq, init_data); - if (ret < 0) - goto err; - - kfree(init_data); - return ret; - -err: - kfree(init_data); - mfd_remove_devices(tps65912->dev); - kfree(tps65912); - return ret; -} - -void tps65912_device_exit(struct tps65912 *tps65912) -{ - mfd_remove_devices(tps65912->dev); - kfree(tps65912); -} - -MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); -MODULE_DESCRIPTION("TPS65912x chip family multi-function driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65912-i2c.c b/ANDROID_3.4.5/drivers/mfd/tps65912-i2c.c deleted file mode 100644 index c041f2c3..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65912-i2c.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * tps65912-i2c.c -- I2C access for TI TPS65912x PMIC - * - * Copyright 2011 Texas Instruments Inc. - * - * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This driver is based on wm8350 implementation. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/i2c.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps65912.h> - -static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg, - int bytes, void *dest) -{ - struct i2c_client *i2c = tps65912->control_data; - struct i2c_msg xfer[2]; - int ret; - - /* Write register */ - xfer[0].addr = i2c->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - - /* Read data */ - xfer[1].addr = i2c->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = bytes; - xfer[1].buf = dest; - - ret = i2c_transfer(i2c->adapter, xfer, 2); - if (ret == 2) - ret = 0; - else if (ret >= 0) - ret = -EIO; - return ret; -} - -static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg, - int bytes, void *src) -{ - struct i2c_client *i2c = tps65912->control_data; - /* we add 1 byte for device register */ - u8 msg[TPS6591X_MAX_REGISTER + 1]; - int ret; - - if (bytes > TPS6591X_MAX_REGISTER) - return -EINVAL; - - msg[0] = reg; - memcpy(&msg[1], src, bytes); - - ret = i2c_master_send(i2c, msg, bytes + 1); - if (ret < 0) - return ret; - if (ret != bytes + 1) - return -EIO; - - return 0; -} - -static int tps65912_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct tps65912 *tps65912; - - tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); - if (tps65912 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, tps65912); - tps65912->dev = &i2c->dev; - tps65912->control_data = i2c; - tps65912->read = tps65912_i2c_read; - tps65912->write = tps65912_i2c_write; - - return tps65912_device_init(tps65912); -} - -static int tps65912_i2c_remove(struct i2c_client *i2c) -{ - struct tps65912 *tps65912 = i2c_get_clientdata(i2c); - - tps65912_device_exit(tps65912); - - return 0; -} - -static const struct i2c_device_id tps65912_i2c_id[] = { - {"tps65912", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id); - -static struct i2c_driver tps65912_i2c_driver = { - .driver = { - .name = "tps65912", - .owner = THIS_MODULE, - }, - .probe = tps65912_i2c_probe, - .remove = tps65912_i2c_remove, - .id_table = tps65912_i2c_id, -}; - -static int __init tps65912_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&tps65912_i2c_driver); - if (ret != 0) - pr_err("Failed to register TPS65912 I2C driver: %d\n", ret); - - return ret; -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(tps65912_i2c_init); - -static void __exit tps65912_i2c_exit(void) -{ - i2c_del_driver(&tps65912_i2c_driver); -} -module_exit(tps65912_i2c_exit); - -MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); -MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/tps65912-irq.c b/ANDROID_3.4.5/drivers/mfd/tps65912-irq.c deleted file mode 100644 index d360a83a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65912-irq.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * tps65912-irq.c -- TI TPS6591x - * - * Copyright 2011 Texas Instruments Inc. - * - * Author: Margarita Olaya <magi@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This driver is based on wm8350 implementation. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/bug.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/mfd/tps65912.h> - -static inline int irq_to_tps65912_irq(struct tps65912 *tps65912, - int irq) -{ - return irq - tps65912->irq_base; -} - -/* - * This is a threaded IRQ handler so can access I2C/SPI. Since the - * IRQ handler explicitly clears the IRQ it handles the IRQ line - * will be reasserted and the physical IRQ will be handled again if - * another interrupt is asserted while we run - in the normal course - * of events this is a rare occurrence so we save I2C/SPI reads. We're - * also assuming that it's rare to get lots of interrupts firing - * simultaneously so try to minimise I/O. - */ -static irqreturn_t tps65912_irq(int irq, void *irq_data) -{ - struct tps65912 *tps65912 = irq_data; - u32 irq_sts; - u32 irq_mask; - u8 reg; - int i; - - - tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); - irq_sts = reg; - tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); - irq_sts |= reg << 8; - tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); - irq_sts |= reg << 16; - tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); - irq_sts |= reg << 24; - - tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); - irq_mask = reg; - tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); - irq_mask |= reg << 8; - tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); - irq_mask |= reg << 16; - tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); - irq_mask |= reg << 24; - - irq_sts &= ~irq_mask; - if (!irq_sts) - return IRQ_NONE; - - for (i = 0; i < tps65912->irq_num; i++) { - if (!(irq_sts & (1 << i))) - continue; - - handle_nested_irq(tps65912->irq_base + i); - } - - /* Write the STS register back to clear IRQs we handled */ - reg = irq_sts & 0xFF; - irq_sts >>= 8; - if (reg) - tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); - reg = irq_sts & 0xFF; - irq_sts >>= 8; - if (reg) - tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); - reg = irq_sts & 0xFF; - irq_sts >>= 8; - if (reg) - tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); - reg = irq_sts & 0xFF; - if (reg) - tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); - - return IRQ_HANDLED; -} - -static void tps65912_irq_lock(struct irq_data *data) -{ - struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); - - mutex_lock(&tps65912->irq_lock); -} - -static void tps65912_irq_sync_unlock(struct irq_data *data) -{ - struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); - u32 reg_mask; - u8 reg; - - tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); - reg_mask = reg; - tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); - reg_mask |= reg << 8; - tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); - reg_mask |= reg << 16; - tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); - reg_mask |= reg << 24; - - if (tps65912->irq_mask != reg_mask) { - reg = tps65912->irq_mask & 0xFF; - tps65912->write(tps65912, TPS65912_INT_MSK, 1, ®); - reg = tps65912->irq_mask >> 8 & 0xFF; - tps65912->write(tps65912, TPS65912_INT_MSK2, 1, ®); - reg = tps65912->irq_mask >> 16 & 0xFF; - tps65912->write(tps65912, TPS65912_INT_MSK3, 1, ®); - reg = tps65912->irq_mask >> 24 & 0xFF; - tps65912->write(tps65912, TPS65912_INT_MSK4, 1, ®); - } - - mutex_unlock(&tps65912->irq_lock); -} - -static void tps65912_irq_enable(struct irq_data *data) -{ - struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); - - tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq)); -} - -static void tps65912_irq_disable(struct irq_data *data) -{ - struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); - - tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq)); -} - -static struct irq_chip tps65912_irq_chip = { - .name = "tps65912", - .irq_bus_lock = tps65912_irq_lock, - .irq_bus_sync_unlock = tps65912_irq_sync_unlock, - .irq_disable = tps65912_irq_disable, - .irq_enable = tps65912_irq_enable, -}; - -int tps65912_irq_init(struct tps65912 *tps65912, int irq, - struct tps65912_platform_data *pdata) -{ - int ret, cur_irq; - int flags = IRQF_ONESHOT; - u8 reg; - - if (!irq) { - dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n"); - return 0; - } - - if (!pdata || !pdata->irq_base) { - dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n"); - return 0; - } - - /* Clear unattended interrupts */ - tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); - tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); - tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); - tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); - tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); - tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); - tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); - tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); - - /* Mask top level interrupts */ - tps65912->irq_mask = 0xFFFFFFFF; - - mutex_init(&tps65912->irq_lock); - tps65912->chip_irq = irq; - tps65912->irq_base = pdata->irq_base; - - tps65912->irq_num = TPS65912_NUM_IRQ; - - /* Register with genirq */ - for (cur_irq = tps65912->irq_base; - cur_irq < tps65912->irq_num + tps65912->irq_base; - cur_irq++) { - irq_set_chip_data(cur_irq, tps65912); - irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(irq, NULL, tps65912_irq, flags, - "tps65912", tps65912); - - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); - if (ret != 0) - dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret); - - return ret; -} - -int tps65912_irq_exit(struct tps65912 *tps65912) -{ - free_irq(tps65912->chip_irq, tps65912); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/tps65912-spi.c b/ANDROID_3.4.5/drivers/mfd/tps65912-spi.c deleted file mode 100644 index 27d3302d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/tps65912-spi.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * tps65912-spi.c -- SPI access for TI TPS65912x PMIC - * - * Copyright 2011 Texas Instruments Inc. - * - * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This driver is based on wm8350 implementation. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tps65912.h> - -static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr, - int bytes, void *src) -{ - struct spi_device *spi = tps65912->control_data; - u8 *data = (u8 *) src; - int ret; - /* bit 23 is the read/write bit */ - unsigned long spi_data = 1 << 23 | addr << 15 | *data; - struct spi_transfer xfer; - struct spi_message msg; - u32 tx_buf, rx_buf; - - tx_buf = spi_data; - rx_buf = 0; - - xfer.tx_buf = &tx_buf; - xfer.rx_buf = NULL; - xfer.len = sizeof(unsigned long); - xfer.bits_per_word = 24; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - ret = spi_sync(spi, &msg); - return ret; -} - -static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr, - int bytes, void *dest) -{ - struct spi_device *spi = tps65912->control_data; - /* bit 23 is the read/write bit */ - unsigned long spi_data = 0 << 23 | addr << 15; - struct spi_transfer xfer; - struct spi_message msg; - int ret; - u8 *data = (u8 *) dest; - u32 tx_buf, rx_buf; - - tx_buf = spi_data; - rx_buf = 0; - - xfer.tx_buf = &tx_buf; - xfer.rx_buf = &rx_buf; - xfer.len = sizeof(unsigned long); - xfer.bits_per_word = 24; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - if (spi == NULL) - return 0; - - ret = spi_sync(spi, &msg); - if (ret == 0) - *data = (u8) (rx_buf & 0xFF); - return ret; -} - -static int __devinit tps65912_spi_probe(struct spi_device *spi) -{ - struct tps65912 *tps65912; - - tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); - if (tps65912 == NULL) - return -ENOMEM; - - tps65912->dev = &spi->dev; - tps65912->control_data = spi; - tps65912->read = tps65912_spi_read; - tps65912->write = tps65912_spi_write; - - spi_set_drvdata(spi, tps65912); - - return tps65912_device_init(tps65912); -} - -static int __devexit tps65912_spi_remove(struct spi_device *spi) -{ - struct tps65912 *tps65912 = spi_get_drvdata(spi); - - tps65912_device_exit(tps65912); - - return 0; -} - -static struct spi_driver tps65912_spi_driver = { - .driver = { - .name = "tps65912", - .owner = THIS_MODULE, - }, - .probe = tps65912_spi_probe, - .remove = __devexit_p(tps65912_spi_remove), -}; - -static int __init tps65912_spi_init(void) -{ - int ret; - - ret = spi_register_driver(&tps65912_spi_driver); - if (ret != 0) - pr_err("Failed to register TPS65912 SPI driver: %d\n", ret); - - return 0; -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(tps65912_spi_init); - -static void __exit tps65912_spi_exit(void) -{ - spi_unregister_driver(&tps65912_spi_driver); -} -module_exit(tps65912_spi_exit); - -MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); -MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl-core.c b/ANDROID_3.4.5/drivers/mfd/twl-core.c deleted file mode 100644 index 7c2267e7..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl-core.c +++ /dev/null @@ -1,1382 +0,0 @@ -/* - * twl_core.c - driver for TWL4030/TWL5030/TWL60X0/TPS659x0 PM - * and audio CODEC devices - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * Modifications to defer interrupt handling to a kernel thread: - * Copyright (C) 2006 MontaVista Software, Inc. - * - * Based on tlv320aic23.c: - * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> - * - * Code cleanup and modifications to IRQ handler. - * by syed khasim <x0khasim@ti.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/device.h> -#include <linux/of.h> -#include <linux/of_irq.h> -#include <linux/of_platform.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> - -#include <linux/regulator/machine.h> - -#include <linux/i2c.h> -#include <linux/i2c/twl.h> - -#include "twl-core.h" - -/* - * The TWL4030 "Triton 2" is one of a family of a multi-function "Power - * Management and System Companion Device" chips originally designed for - * use in OMAP2 and OMAP 3 based systems. Its control interfaces use I2C, - * often at around 3 Mbit/sec, including for interrupt handling. - * - * This driver core provides genirq support for the interrupts emitted, - * by the various modules, and exports register access primitives. - * - * FIXME this driver currently requires use of the first interrupt line - * (and associated registers). - */ - -#define DRIVER_NAME "twl" - -#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE) -#define twl_has_keypad() true -#else -#define twl_has_keypad() false -#endif - -#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE) -#define twl_has_gpio() true -#else -#define twl_has_gpio() false -#endif - -#if defined(CONFIG_REGULATOR_TWL4030) \ - || defined(CONFIG_REGULATOR_TWL4030_MODULE) -#define twl_has_regulator() true -#else -#define twl_has_regulator() false -#endif - -#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) -#define twl_has_madc() true -#else -#define twl_has_madc() false -#endif - -#ifdef CONFIG_TWL4030_POWER -#define twl_has_power() true -#else -#define twl_has_power() false -#endif - -#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE) -#define twl_has_rtc() true -#else -#define twl_has_rtc() false -#endif - -#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\ - defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE) -#define twl_has_usb() true -#else -#define twl_has_usb() false -#endif - -#if defined(CONFIG_TWL4030_WATCHDOG) || \ - defined(CONFIG_TWL4030_WATCHDOG_MODULE) -#define twl_has_watchdog() true -#else -#define twl_has_watchdog() false -#endif - -#if defined(CONFIG_MFD_TWL4030_AUDIO) || \ - defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) -#define twl_has_codec() true -#else -#define twl_has_codec() false -#endif - -#if defined(CONFIG_CHARGER_TWL4030) || defined(CONFIG_CHARGER_TWL4030_MODULE) -#define twl_has_bci() true -#else -#define twl_has_bci() false -#endif - -/* Triton Core internal information (BEGIN) */ - -/* Last - for index max*/ -#define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG - -#define TWL_NUM_SLAVES 4 - -#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \ - || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE) -#define twl_has_pwrbutton() true -#else -#define twl_has_pwrbutton() false -#endif - -#define SUB_CHIP_ID0 0 -#define SUB_CHIP_ID1 1 -#define SUB_CHIP_ID2 2 -#define SUB_CHIP_ID3 3 -#define SUB_CHIP_ID_INVAL 0xff - -#define TWL_MODULE_LAST TWL4030_MODULE_LAST - -/* Base Address defns for twl4030_map[] */ - -/* subchip/slave 0 - USB ID */ -#define TWL4030_BASEADD_USB 0x0000 - -/* subchip/slave 1 - AUD ID */ -#define TWL4030_BASEADD_AUDIO_VOICE 0x0000 -#define TWL4030_BASEADD_GPIO 0x0098 -#define TWL4030_BASEADD_INTBR 0x0085 -#define TWL4030_BASEADD_PIH 0x0080 -#define TWL4030_BASEADD_TEST 0x004C - -/* subchip/slave 2 - AUX ID */ -#define TWL4030_BASEADD_INTERRUPTS 0x00B9 -#define TWL4030_BASEADD_LED 0x00EE -#define TWL4030_BASEADD_MADC 0x0000 -#define TWL4030_BASEADD_MAIN_CHARGE 0x0074 -#define TWL4030_BASEADD_PRECHARGE 0x00AA -#define TWL4030_BASEADD_PWM0 0x00F8 -#define TWL4030_BASEADD_PWM1 0x00FB -#define TWL4030_BASEADD_PWMA 0x00EF -#define TWL4030_BASEADD_PWMB 0x00F1 -#define TWL4030_BASEADD_KEYPAD 0x00D2 - -#define TWL5031_BASEADD_ACCESSORY 0x0074 /* Replaces Main Charge */ -#define TWL5031_BASEADD_INTERRUPTS 0x00B9 /* Different than TWL4030's - one */ - -/* subchip/slave 3 - POWER ID */ -#define TWL4030_BASEADD_BACKUP 0x0014 -#define TWL4030_BASEADD_INT 0x002E -#define TWL4030_BASEADD_PM_MASTER 0x0036 -#define TWL4030_BASEADD_PM_RECEIVER 0x005B -#define TWL4030_BASEADD_RTC 0x001C -#define TWL4030_BASEADD_SECURED_REG 0x0000 - -/* Triton Core internal information (END) */ - - -/* subchip/slave 0 0x48 - POWER */ -#define TWL6030_BASEADD_RTC 0x0000 -#define TWL6030_BASEADD_MEM 0x0017 -#define TWL6030_BASEADD_PM_MASTER 0x001F -#define TWL6030_BASEADD_PM_SLAVE_MISC 0x0030 /* PM_RECEIVER */ -#define TWL6030_BASEADD_PM_MISC 0x00E2 -#define TWL6030_BASEADD_PM_PUPD 0x00F0 - -/* subchip/slave 1 0x49 - FEATURE */ -#define TWL6030_BASEADD_USB 0x0000 -#define TWL6030_BASEADD_GPADC_CTRL 0x002E -#define TWL6030_BASEADD_AUX 0x0090 -#define TWL6030_BASEADD_PWM 0x00BA -#define TWL6030_BASEADD_GASGAUGE 0x00C0 -#define TWL6030_BASEADD_PIH 0x00D0 -#define TWL6030_BASEADD_CHARGER 0x00E0 -#define TWL6025_BASEADD_CHARGER 0x00DA - -/* subchip/slave 2 0x4A - DFT */ -#define TWL6030_BASEADD_DIEID 0x00C0 - -/* subchip/slave 3 0x4B - AUDIO */ -#define TWL6030_BASEADD_AUDIO 0x0000 -#define TWL6030_BASEADD_RSV 0x0000 -#define TWL6030_BASEADD_ZERO 0x0000 - -/* Few power values */ -#define R_CFG_BOOT 0x05 - -/* some fields in R_CFG_BOOT */ -#define HFCLK_FREQ_19p2_MHZ (1 << 0) -#define HFCLK_FREQ_26_MHZ (2 << 0) -#define HFCLK_FREQ_38p4_MHZ (3 << 0) -#define HIGH_PERF_SQ (1 << 3) -#define CK32K_LOWPWR_EN (1 << 7) - - -/* chip-specific feature flags, for i2c_device_id.driver_data */ -#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */ -#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ -#define TWL5031 BIT(2) /* twl5031 has different registers */ -#define TWL6030_CLASS BIT(3) /* TWL6030 class */ - -/*----------------------------------------------------------------------*/ - -/* is driver active, bound to a chip? */ -static bool inuse; - -/* TWL IDCODE Register value */ -static u32 twl_idcode; - -static unsigned int twl_id; -unsigned int twl_rev(void) -{ - return twl_id; -} -EXPORT_SYMBOL(twl_rev); - -/* Structure for each TWL4030/TWL6030 Slave */ -struct twl_client { - struct i2c_client *client; - u8 address; - - /* max numb of i2c_msg required is for read =2 */ - struct i2c_msg xfer_msg[2]; - - /* To lock access to xfer_msg */ - struct mutex xfer_lock; -}; - -static struct twl_client twl_modules[TWL_NUM_SLAVES]; - -/* mapping the module id to slave id and base address */ -struct twl_mapping { - unsigned char sid; /* Slave ID */ - unsigned char base; /* base address */ -}; -static struct twl_mapping *twl_map; - -static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { - /* - * NOTE: don't change this table without updating the - * <linux/i2c/twl.h> defines for TWL4030_MODULE_* - * so they continue to match the order in this table. - */ - - { 0, TWL4030_BASEADD_USB }, - - { 1, TWL4030_BASEADD_AUDIO_VOICE }, - { 1, TWL4030_BASEADD_GPIO }, - { 1, TWL4030_BASEADD_INTBR }, - { 1, TWL4030_BASEADD_PIH }, - { 1, TWL4030_BASEADD_TEST }, - - { 2, TWL4030_BASEADD_KEYPAD }, - { 2, TWL4030_BASEADD_MADC }, - { 2, TWL4030_BASEADD_INTERRUPTS }, - { 2, TWL4030_BASEADD_LED }, - { 2, TWL4030_BASEADD_MAIN_CHARGE }, - { 2, TWL4030_BASEADD_PRECHARGE }, - { 2, TWL4030_BASEADD_PWM0 }, - { 2, TWL4030_BASEADD_PWM1 }, - { 2, TWL4030_BASEADD_PWMA }, - { 2, TWL4030_BASEADD_PWMB }, - { 2, TWL5031_BASEADD_ACCESSORY }, - { 2, TWL5031_BASEADD_INTERRUPTS }, - - { 3, TWL4030_BASEADD_BACKUP }, - { 3, TWL4030_BASEADD_INT }, - { 3, TWL4030_BASEADD_PM_MASTER }, - { 3, TWL4030_BASEADD_PM_RECEIVER }, - { 3, TWL4030_BASEADD_RTC }, - { 3, TWL4030_BASEADD_SECURED_REG }, -}; - -static struct twl_mapping twl6030_map[] = { - /* - * NOTE: don't change this table without updating the - * <linux/i2c/twl.h> defines for TWL4030_MODULE_* - * so they continue to match the order in this table. - */ - { SUB_CHIP_ID1, TWL6030_BASEADD_USB }, - { SUB_CHIP_ID_INVAL, TWL6030_BASEADD_AUDIO }, - { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID1, TWL6030_BASEADD_PIH }, - - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID1, TWL6030_BASEADD_GPADC_CTRL }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - - { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER }, - { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE }, - { SUB_CHIP_ID1, TWL6030_BASEADD_PWM }, - { SUB_CHIP_ID0, TWL6030_BASEADD_ZERO }, - { SUB_CHIP_ID1, TWL6030_BASEADD_ZERO }, - - { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, - { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, - { SUB_CHIP_ID0, TWL6030_BASEADD_PM_MASTER }, - { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_MISC }, - - { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, - { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, - { SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER }, -}; - -/*----------------------------------------------------------------------*/ - -/* Exported Functions */ - -/** - * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 - * @mod_no: module number - * @value: an array of num_bytes+1 containing data to write - * @reg: register address (just offset will do) - * @num_bytes: number of bytes to transfer - * - * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and - * valid data starts at Offset 1. - * - * Returns the result of operation - 0 is success - */ -int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) -{ - int ret; - int sid; - struct twl_client *twl; - struct i2c_msg *msg; - - if (unlikely(mod_no > TWL_MODULE_LAST)) { - pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); - return -EPERM; - } - if (unlikely(!inuse)) { - pr_err("%s: not initialized\n", DRIVER_NAME); - return -EPERM; - } - sid = twl_map[mod_no].sid; - if (unlikely(sid == SUB_CHIP_ID_INVAL)) { - pr_err("%s: module %d is not part of the pmic\n", - DRIVER_NAME, mod_no); - return -EINVAL; - } - twl = &twl_modules[sid]; - - mutex_lock(&twl->xfer_lock); - /* - * [MSG1]: fill the register address data - * fill the data Tx buffer - */ - msg = &twl->xfer_msg[0]; - msg->addr = twl->address; - msg->len = num_bytes + 1; - msg->flags = 0; - msg->buf = value; - /* over write the first byte of buffer with the register address */ - *value = twl_map[mod_no].base + reg; - ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1); - mutex_unlock(&twl->xfer_lock); - - /* i2c_transfer returns number of messages transferred */ - if (ret != 1) { - pr_err("%s: i2c_write failed to transfer all messages\n", - DRIVER_NAME); - if (ret < 0) - return ret; - else - return -EIO; - } else { - return 0; - } -} -EXPORT_SYMBOL(twl_i2c_write); - -/** - * twl_i2c_read - Reads a n bit register in TWL4030/TWL5030/TWL60X0 - * @mod_no: module number - * @value: an array of num_bytes containing data to be read - * @reg: register address (just offset will do) - * @num_bytes: number of bytes to transfer - * - * Returns result of operation - num_bytes is success else failure. - */ -int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) -{ - int ret; - u8 val; - int sid; - struct twl_client *twl; - struct i2c_msg *msg; - - if (unlikely(mod_no > TWL_MODULE_LAST)) { - pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); - return -EPERM; - } - if (unlikely(!inuse)) { - pr_err("%s: not initialized\n", DRIVER_NAME); - return -EPERM; - } - sid = twl_map[mod_no].sid; - if (unlikely(sid == SUB_CHIP_ID_INVAL)) { - pr_err("%s: module %d is not part of the pmic\n", - DRIVER_NAME, mod_no); - return -EINVAL; - } - twl = &twl_modules[sid]; - - mutex_lock(&twl->xfer_lock); - /* [MSG1] fill the register address data */ - msg = &twl->xfer_msg[0]; - msg->addr = twl->address; - msg->len = 1; - msg->flags = 0; /* Read the register value */ - val = twl_map[mod_no].base + reg; - msg->buf = &val; - /* [MSG2] fill the data rx buffer */ - msg = &twl->xfer_msg[1]; - msg->addr = twl->address; - msg->flags = I2C_M_RD; /* Read the register value */ - msg->len = num_bytes; /* only n bytes */ - msg->buf = value; - ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2); - mutex_unlock(&twl->xfer_lock); - - /* i2c_transfer returns number of messages transferred */ - if (ret != 2) { - pr_err("%s: i2c_read failed to transfer all messages\n", - DRIVER_NAME); - if (ret < 0) - return ret; - else - return -EIO; - } else { - return 0; - } -} -EXPORT_SYMBOL(twl_i2c_read); - -/** - * twl_i2c_write_u8 - Writes a 8 bit register in TWL4030/TWL5030/TWL60X0 - * @mod_no: module number - * @value: the value to be written 8 bit - * @reg: register address (just offset will do) - * - * Returns result of operation - 0 is success - */ -int twl_i2c_write_u8(u8 mod_no, u8 value, u8 reg) -{ - - /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */ - u8 temp_buffer[2] = { 0 }; - /* offset 1 contains the data */ - temp_buffer[1] = value; - return twl_i2c_write(mod_no, temp_buffer, reg, 1); -} -EXPORT_SYMBOL(twl_i2c_write_u8); - -/** - * twl_i2c_read_u8 - Reads a 8 bit register from TWL4030/TWL5030/TWL60X0 - * @mod_no: module number - * @value: the value read 8 bit - * @reg: register address (just offset will do) - * - * Returns result of operation - 0 is success - */ -int twl_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) -{ - return twl_i2c_read(mod_no, value, reg, 1); -} -EXPORT_SYMBOL(twl_i2c_read_u8); - -/*----------------------------------------------------------------------*/ - -/** - * twl_read_idcode_register - API to read the IDCODE register. - * - * Unlocks the IDCODE register and read the 32 bit value. - */ -static int twl_read_idcode_register(void) -{ - int err; - - err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, - REG_UNLOCK_TEST_REG); - if (err) { - pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err); - goto fail; - } - - err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), - REG_IDCODE_7_0, 4); - if (err) { - pr_err("TWL4030: unable to read IDCODE -%d\n", err); - goto fail; - } - - err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG); - if (err) - pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err); -fail: - return err; -} - -/** - * twl_get_type - API to get TWL Si type. - * - * Api to get the TWL Si type from IDCODE value. - */ -int twl_get_type(void) -{ - return TWL_SIL_TYPE(twl_idcode); -} -EXPORT_SYMBOL_GPL(twl_get_type); - -/** - * twl_get_version - API to get TWL Si version. - * - * Api to get the TWL Si version from IDCODE value. - */ -int twl_get_version(void) -{ - return TWL_SIL_REV(twl_idcode); -} -EXPORT_SYMBOL_GPL(twl_get_version); - -static struct device * -add_numbered_child(unsigned chip, const char *name, int num, - void *pdata, unsigned pdata_len, - bool can_wakeup, int irq0, int irq1) -{ - struct platform_device *pdev; - struct twl_client *twl = &twl_modules[chip]; - int status; - - pdev = platform_device_alloc(name, num); - if (!pdev) { - dev_dbg(&twl->client->dev, "can't alloc dev\n"); - status = -ENOMEM; - goto err; - } - - device_init_wakeup(&pdev->dev, can_wakeup); - pdev->dev.parent = &twl->client->dev; - - if (pdata) { - status = platform_device_add_data(pdev, pdata, pdata_len); - if (status < 0) { - dev_dbg(&pdev->dev, "can't add platform_data\n"); - goto err; - } - } - - if (irq0) { - struct resource r[2] = { - { .start = irq0, .flags = IORESOURCE_IRQ, }, - { .start = irq1, .flags = IORESOURCE_IRQ, }, - }; - - status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1); - if (status < 0) { - dev_dbg(&pdev->dev, "can't add irqs\n"); - goto err; - } - } - - status = platform_device_add(pdev); - -err: - if (status < 0) { - platform_device_put(pdev); - dev_err(&twl->client->dev, "can't add %s dev\n", name); - return ERR_PTR(status); - } - return &pdev->dev; -} - -static inline struct device *add_child(unsigned chip, const char *name, - void *pdata, unsigned pdata_len, - bool can_wakeup, int irq0, int irq1) -{ - return add_numbered_child(chip, name, -1, pdata, pdata_len, - can_wakeup, irq0, irq1); -} - -static struct device * -add_regulator_linked(int num, struct regulator_init_data *pdata, - struct regulator_consumer_supply *consumers, - unsigned num_consumers, unsigned long features) -{ - unsigned sub_chip_id; - struct twl_regulator_driver_data drv_data; - - /* regulator framework demands init_data ... */ - if (!pdata) - return NULL; - - if (consumers) { - pdata->consumer_supplies = consumers; - pdata->num_consumer_supplies = num_consumers; - } - - if (pdata->driver_data) { - /* If we have existing drv_data, just add the flags */ - struct twl_regulator_driver_data *tmp; - tmp = pdata->driver_data; - tmp->features |= features; - } else { - /* add new driver data struct, used only during init */ - drv_data.features = features; - drv_data.set_voltage = NULL; - drv_data.get_voltage = NULL; - drv_data.data = NULL; - pdata->driver_data = &drv_data; - } - - /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ - sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; - return add_numbered_child(sub_chip_id, "twl_reg", num, - pdata, sizeof(*pdata), false, 0, 0); -} - -static struct device * -add_regulator(int num, struct regulator_init_data *pdata, - unsigned long features) -{ - return add_regulator_linked(num, pdata, NULL, 0, features); -} - -/* - * NOTE: We know the first 8 IRQs after pdata->base_irq are - * for the PIH, and the next are for the PWR_INT SIH, since - * that's how twl_init_irq() sets things up. - */ - -static int -add_children(struct twl4030_platform_data *pdata, unsigned irq_base, - unsigned long features) -{ - struct device *child; - unsigned sub_chip_id; - - if (twl_has_gpio() && pdata->gpio) { - child = add_child(SUB_CHIP_ID1, "twl4030_gpio", - pdata->gpio, sizeof(*pdata->gpio), - false, irq_base + GPIO_INTR_OFFSET, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_keypad() && pdata->keypad) { - child = add_child(SUB_CHIP_ID2, "twl4030_keypad", - pdata->keypad, sizeof(*pdata->keypad), - true, irq_base + KEYPAD_INTR_OFFSET, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_madc() && pdata->madc) { - child = add_child(2, "twl4030_madc", - pdata->madc, sizeof(*pdata->madc), - true, irq_base + MADC_INTR_OFFSET, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_rtc()) { - /* - * REVISIT platform_data here currently might expose the - * "msecure" line ... but for now we just expect board - * setup to tell the chip "it's always ok to SET_TIME". - * Eventually, Linux might become more aware of such - * HW security concerns, and "least privilege". - */ - sub_chip_id = twl_map[TWL_MODULE_RTC].sid; - child = add_child(sub_chip_id, "twl_rtc", - NULL, 0, - true, irq_base + RTC_INTR_OFFSET, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_usb() && pdata->usb && twl_class_is_4030()) { - - static struct regulator_consumer_supply usb1v5 = { - .supply = "usb1v5", - }; - static struct regulator_consumer_supply usb1v8 = { - .supply = "usb1v8", - }; - static struct regulator_consumer_supply usb3v1 = { - .supply = "usb3v1", - }; - - /* First add the regulators so that they can be used by transceiver */ - if (twl_has_regulator()) { - /* this is a template that gets copied */ - struct regulator_init_data usb_fixed = { - .constraints.valid_modes_mask = - REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .constraints.valid_ops_mask = - REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }; - - child = add_regulator_linked(TWL4030_REG_VUSB1V5, - &usb_fixed, &usb1v5, 1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator_linked(TWL4030_REG_VUSB1V8, - &usb_fixed, &usb1v8, 1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator_linked(TWL4030_REG_VUSB3V1, - &usb_fixed, &usb3v1, 1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - } - - child = add_child(0, "twl4030_usb", - pdata->usb, sizeof(*pdata->usb), - true, - /* irq0 = USB_PRES, irq1 = USB */ - irq_base + USB_PRES_INTR_OFFSET, - irq_base + USB_INTR_OFFSET); - - if (IS_ERR(child)) - return PTR_ERR(child); - - /* we need to connect regulators to this transceiver */ - if (twl_has_regulator() && child) { - usb1v5.dev_name = dev_name(child); - usb1v8.dev_name = dev_name(child); - usb3v1.dev_name = dev_name(child); - } - } - if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { - - static struct regulator_consumer_supply usb3v3; - int regulator; - - if (twl_has_regulator()) { - /* this is a template that gets copied */ - struct regulator_init_data usb_fixed = { - .constraints.valid_modes_mask = - REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .constraints.valid_ops_mask = - REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }; - - if (features & TWL6025_SUBCLASS) { - usb3v3.supply = "ldousb"; - regulator = TWL6025_REG_LDOUSB; - } else { - usb3v3.supply = "vusb"; - regulator = TWL6030_REG_VUSB; - } - child = add_regulator_linked(regulator, &usb_fixed, - &usb3v3, 1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - pdata->usb->features = features; - - child = add_child(0, "twl6030_usb", - pdata->usb, sizeof(*pdata->usb), - true, - /* irq1 = VBUS_PRES, irq0 = USB ID */ - irq_base + USBOTG_INTR_OFFSET, - irq_base + USB_PRES_INTR_OFFSET); - - if (IS_ERR(child)) - return PTR_ERR(child); - /* we need to connect regulators to this transceiver */ - if (twl_has_regulator() && child) - usb3v3.dev_name = dev_name(child); - } else if (twl_has_regulator() && twl_class_is_6030()) { - if (features & TWL6025_SUBCLASS) - child = add_regulator(TWL6025_REG_LDOUSB, - pdata->ldousb, features); - else - child = add_regulator(TWL6030_REG_VUSB, - pdata->vusb, features); - - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_watchdog() && twl_class_is_4030()) { - child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_pwrbutton() && twl_class_is_4030()) { - child = add_child(1, "twl4030_pwrbutton", - NULL, 0, true, irq_base + 8 + 0, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - if (twl_has_codec() && pdata->audio && twl_class_is_4030()) { - sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; - child = add_child(sub_chip_id, "twl4030-audio", - pdata->audio, sizeof(*pdata->audio), - false, 0, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* twl4030 regulators */ - if (twl_has_regulator() && twl_class_is_4030()) { - child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VIO, pdata->vio, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VDAC, pdata->vdac, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator((features & TWL4030_VAUX2) - ? TWL4030_REG_VAUX2_4030 - : TWL4030_REG_VAUX2, - pdata->vaux2, features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* maybe add LDOs that are omitted on cost-reduced parts */ - if (twl_has_regulator() && !(features & TPS_SUBSET) - && twl_class_is_4030()) { - child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VSIM, pdata->vsim, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* twl6030 regulators */ - if (twl_has_regulator() && twl_class_is_6030() && - !(features & TWL6025_SUBCLASS)) { - child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_V1V8, pdata->v1v8, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_V2V1, pdata->v2v1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VPP, pdata->vpp, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VDAC, pdata->vdac, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* 6030 and 6025 share this regulator */ - if (twl_has_regulator() && twl_class_is_6030()) { - child = add_regulator(TWL6030_REG_VANA, pdata->vana, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - /* twl6025 regulators */ - if (twl_has_regulator() && twl_class_is_6030() && - (features & TWL6025_SUBCLASS)) { - child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO1, pdata->ldo1, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO7, pdata->ldo7, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO6, pdata->ldo6, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDOLN, pdata->ldoln, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO2, pdata->ldo2, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO4, pdata->ldo4, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_LDO3, pdata->ldo3, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_SMPS3, pdata->smps3, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_SMPS4, pdata->smps4, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - child = add_regulator(TWL6025_REG_VIO, pdata->vio6025, - features); - if (IS_ERR(child)) - return PTR_ERR(child); - - } - - if (twl_has_bci() && pdata->bci && - !(features & (TPS_SUBSET | TWL5031))) { - child = add_child(3, "twl4030_bci", - pdata->bci, sizeof(*pdata->bci), false, - /* irq0 = CHG_PRES, irq1 = BCI */ - irq_base + BCI_PRES_INTR_OFFSET, - irq_base + BCI_INTR_OFFSET); - if (IS_ERR(child)) - return PTR_ERR(child); - } - - return 0; -} - -/*----------------------------------------------------------------------*/ - -/* - * These three functions initialize the on-chip clock framework, - * letting it generate the right frequencies for USB, MADC, and - * other purposes. - */ -static inline int __init protect_pm_master(void) -{ - int e = 0; - - e = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - return e; -} - -static inline int __init unprotect_pm_master(void) -{ - int e = 0; - - e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - - return e; -} - -static void clocks_init(struct device *dev, - struct twl4030_clock_init_data *clock) -{ - int e = 0; - struct clk *osc; - u32 rate; - u8 ctrl = HFCLK_FREQ_26_MHZ; - -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - if (cpu_is_omap2430()) - osc = clk_get(dev, "osc_ck"); - else - osc = clk_get(dev, "osc_sys_ck"); - - if (IS_ERR(osc)) { - printk(KERN_WARNING "Skipping twl internal clock init and " - "using bootloader value (unknown osc rate)\n"); - return; - } - - rate = clk_get_rate(osc); - clk_put(osc); - -#else - /* REVISIT for non-OMAP systems, pass the clock rate from - * board init code, using platform_data. - */ - osc = ERR_PTR(-EIO); - - printk(KERN_WARNING "Skipping twl internal clock init and " - "using bootloader value (unknown osc rate)\n"); - - return; -#endif - - switch (rate) { - case 19200000: - ctrl = HFCLK_FREQ_19p2_MHZ; - break; - case 26000000: - ctrl = HFCLK_FREQ_26_MHZ; - break; - case 38400000: - ctrl = HFCLK_FREQ_38p4_MHZ; - break; - } - - ctrl |= HIGH_PERF_SQ; - if (clock && clock->ck32k_lowpwr_enable) - ctrl |= CK32K_LOWPWR_EN; - - e |= unprotect_pm_master(); - /* effect->MADC+USB ck en */ - e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); - e |= protect_pm_master(); - - if (e < 0) - pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e); -} - -/*----------------------------------------------------------------------*/ - - -static int twl_remove(struct i2c_client *client) -{ - unsigned i, num_slaves; - int status; - - if (twl_class_is_4030()) { - status = twl4030_exit_irq(); - num_slaves = TWL_NUM_SLAVES; - } else { - status = twl6030_exit_irq(); - num_slaves = TWL_NUM_SLAVES - 1; - } - - if (status < 0) - return status; - - for (i = 0; i < num_slaves; i++) { - struct twl_client *twl = &twl_modules[i]; - - if (twl->client && twl->client != client) - i2c_unregister_device(twl->client); - twl_modules[i].client = NULL; - } - inuse = false; - return 0; -} - -/* NOTE: This driver only handles a single twl4030/tps659x0 chip */ -static int __devinit -twl_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct twl4030_platform_data *pdata = client->dev.platform_data; - struct device_node *node = client->dev.of_node; - int irq_base = 0; - int status; - unsigned i, num_slaves; - - if (node && !pdata) { - /* - * XXX: Temporary pdata until the information is correctly - * retrieved by every TWL modules from DT. - */ - pdata = devm_kzalloc(&client->dev, - sizeof(struct twl4030_platform_data), - GFP_KERNEL); - if (!pdata) - return -ENOMEM; - } - - if (!pdata) { - dev_dbg(&client->dev, "no platform data?\n"); - return -EINVAL; - } - - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { - dev_dbg(&client->dev, "can't talk I2C?\n"); - return -EIO; - } - - if (inuse) { - dev_dbg(&client->dev, "driver is already in use\n"); - return -EBUSY; - } - - if ((id->driver_data) & TWL6030_CLASS) { - twl_id = TWL6030_CLASS_ID; - twl_map = &twl6030_map[0]; - num_slaves = TWL_NUM_SLAVES - 1; - } else { - twl_id = TWL4030_CLASS_ID; - twl_map = &twl4030_map[0]; - num_slaves = TWL_NUM_SLAVES; - } - - for (i = 0; i < num_slaves; i++) { - struct twl_client *twl = &twl_modules[i]; - - twl->address = client->addr + i; - if (i == 0) { - twl->client = client; - } else { - twl->client = i2c_new_dummy(client->adapter, - twl->address); - if (!twl->client) { - dev_err(&client->dev, - "can't attach client %d\n", i); - status = -ENOMEM; - goto fail; - } - } - mutex_init(&twl->xfer_lock); - } - - inuse = true; - - /* setup clock framework */ - clocks_init(&client->dev, pdata->clock); - - /* read TWL IDCODE Register */ - if (twl_id == TWL4030_CLASS_ID) { - status = twl_read_idcode_register(); - WARN(status < 0, "Error: reading twl_idcode register value\n"); - } - - /* load power event scripts */ - if (twl_has_power() && pdata->power) - twl4030_power_init(pdata->power); - - /* Maybe init the T2 Interrupt subsystem */ - if (client->irq) { - if (twl_class_is_4030()) { - twl4030_init_chip_irq(id->name); - irq_base = twl4030_init_irq(&client->dev, client->irq); - } else { - irq_base = twl6030_init_irq(&client->dev, client->irq); - } - - if (irq_base < 0) { - status = irq_base; - goto fail; - } - } - - /* - * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. - * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, - * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. - */ - if (twl_class_is_4030()) { - u8 temp; - - twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1); - temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ - I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); - twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); - } - - status = -ENODEV; - if (node) - status = of_platform_populate(node, NULL, NULL, &client->dev); - if (status) - status = add_children(pdata, irq_base, id->driver_data); - -fail: - if (status < 0) - twl_remove(client); - - return status; -} - -static const struct i2c_device_id twl_ids[] = { - { "twl4030", TWL4030_VAUX2 }, /* "Triton 2" */ - { "twl5030", 0 }, /* T2 updated */ - { "twl5031", TWL5031 }, /* TWL5030 updated */ - { "tps65950", 0 }, /* catalog version of twl5030 */ - { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ - { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */ - { "tps65921", TPS_SUBSET }, /* fewer LDOs; no codec, no LED - and vibrator. Charger in USB module*/ - { "twl6030", TWL6030_CLASS }, /* "Phoenix power chip" */ - { "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */ - { /* end of list */ }, -}; -MODULE_DEVICE_TABLE(i2c, twl_ids); - -/* One Client Driver , 4 Clients */ -static struct i2c_driver twl_driver = { - .driver.name = DRIVER_NAME, - .id_table = twl_ids, - .probe = twl_probe, - .remove = twl_remove, -}; - -static int __init twl_init(void) -{ - return i2c_add_driver(&twl_driver); -} -subsys_initcall(twl_init); - -static void __exit twl_exit(void) -{ - i2c_del_driver(&twl_driver); -} -module_exit(twl_exit); - -MODULE_AUTHOR("Texas Instruments, Inc."); -MODULE_DESCRIPTION("I2C Core interface for TWL"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl-core.h b/ANDROID_3.4.5/drivers/mfd/twl-core.h deleted file mode 100644 index 6ff99dce..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl-core.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __TWL_CORE_H__ -#define __TWL_CORE_H__ - -extern int twl6030_init_irq(struct device *dev, int irq_num); -extern int twl6030_exit_irq(void); -extern int twl4030_init_irq(struct device *dev, int irq_num); -extern int twl4030_exit_irq(void); -extern int twl4030_init_chip_irq(const char *chip); - -#endif /* __TWL_CORE_H__ */ diff --git a/ANDROID_3.4.5/drivers/mfd/twl4030-audio.c b/ANDROID_3.4.5/drivers/mfd/twl4030-audio.c deleted file mode 100644 index 838ce4eb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl4030-audio.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * MFD driver for twl4030 audio submodule, which contains an audio codec, and - * the vibra control. - * - * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> - * - * Copyright: (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/i2c/twl.h> -#include <linux/mfd/core.h> -#include <linux/mfd/twl4030-audio.h> - -#define TWL4030_AUDIO_CELLS 2 - -static struct platform_device *twl4030_audio_dev; - -struct twl4030_audio_resource { - int request_count; - u8 reg; - u8 mask; -}; - -struct twl4030_audio { - unsigned int audio_mclk; - struct mutex mutex; - struct twl4030_audio_resource resource[TWL4030_AUDIO_RES_MAX]; - struct mfd_cell cells[TWL4030_AUDIO_CELLS]; -}; - -/* - * Modify the resource, the function returns the content of the register - * after the modification. - */ -static int twl4030_audio_set_resource(enum twl4030_audio_res id, int enable) -{ - struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); - u8 val; - - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, - audio->resource[id].reg); - - if (enable) - val |= audio->resource[id].mask; - else - val &= ~audio->resource[id].mask; - - twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - val, audio->resource[id].reg); - - return val; -} - -static inline int twl4030_audio_get_resource(enum twl4030_audio_res id) -{ - struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); - u8 val; - - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, - audio->resource[id].reg); - - return val; -} - -/* - * Enable the resource. - * The function returns with error or the content of the register - */ -int twl4030_audio_enable_resource(enum twl4030_audio_res id) -{ - struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); - int val; - - if (id >= TWL4030_AUDIO_RES_MAX) { - dev_err(&twl4030_audio_dev->dev, - "Invalid resource ID (%u)\n", id); - return -EINVAL; - } - - mutex_lock(&audio->mutex); - if (!audio->resource[id].request_count) - /* Resource was disabled, enable it */ - val = twl4030_audio_set_resource(id, 1); - else - val = twl4030_audio_get_resource(id); - - audio->resource[id].request_count++; - mutex_unlock(&audio->mutex); - - return val; -} -EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource); - -/* - * Disable the resource. - * The function returns with error or the content of the register - */ -int twl4030_audio_disable_resource(unsigned id) -{ - struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); - int val; - - if (id >= TWL4030_AUDIO_RES_MAX) { - dev_err(&twl4030_audio_dev->dev, - "Invalid resource ID (%u)\n", id); - return -EINVAL; - } - - mutex_lock(&audio->mutex); - if (!audio->resource[id].request_count) { - dev_err(&twl4030_audio_dev->dev, - "Resource has been disabled already (%u)\n", id); - mutex_unlock(&audio->mutex); - return -EPERM; - } - audio->resource[id].request_count--; - - if (!audio->resource[id].request_count) - /* Resource can be disabled now */ - val = twl4030_audio_set_resource(id, 0); - else - val = twl4030_audio_get_resource(id); - - mutex_unlock(&audio->mutex); - - return val; -} -EXPORT_SYMBOL_GPL(twl4030_audio_disable_resource); - -unsigned int twl4030_audio_get_mclk(void) -{ - struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); - - return audio->audio_mclk; -} -EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); - -static int __devinit twl4030_audio_probe(struct platform_device *pdev) -{ - struct twl4030_audio *audio; - struct twl4030_audio_data *pdata = pdev->dev.platform_data; - struct mfd_cell *cell = NULL; - int ret, childs = 0; - u8 val; - - if (!pdata) { - dev_err(&pdev->dev, "Platform data is missing\n"); - return -EINVAL; - } - - /* Configure APLL_INFREQ and disable APLL if enabled */ - val = 0; - switch (pdata->audio_mclk) { - case 19200000: - val |= TWL4030_APLL_INFREQ_19200KHZ; - break; - case 26000000: - val |= TWL4030_APLL_INFREQ_26000KHZ; - break; - case 38400000: - val |= TWL4030_APLL_INFREQ_38400KHZ; - break; - default: - dev_err(&pdev->dev, "Invalid audio_mclk\n"); - return -EINVAL; - } - twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - val, TWL4030_REG_APLL_CTL); - - audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL); - if (!audio) - return -ENOMEM; - - platform_set_drvdata(pdev, audio); - - twl4030_audio_dev = pdev; - mutex_init(&audio->mutex); - audio->audio_mclk = pdata->audio_mclk; - - /* Codec power */ - audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE; - audio->resource[TWL4030_AUDIO_RES_POWER].mask = TWL4030_CODECPDZ; - - /* PLL */ - audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL; - audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN; - - if (pdata->codec) { - cell = &audio->cells[childs]; - cell->name = "twl4030-codec"; - cell->platform_data = pdata->codec; - cell->pdata_size = sizeof(*pdata->codec); - childs++; - } - if (pdata->vibra) { - cell = &audio->cells[childs]; - cell->name = "twl4030-vibra"; - cell->platform_data = pdata->vibra; - cell->pdata_size = sizeof(*pdata->vibra); - childs++; - } - - if (childs) - ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, - childs, NULL, 0); - else { - dev_err(&pdev->dev, "No platform data found for childs\n"); - ret = -ENODEV; - } - - if (!ret) - return 0; - - platform_set_drvdata(pdev, NULL); - kfree(audio); - twl4030_audio_dev = NULL; - return ret; -} - -static int __devexit twl4030_audio_remove(struct platform_device *pdev) -{ - struct twl4030_audio *audio = platform_get_drvdata(pdev); - - mfd_remove_devices(&pdev->dev); - platform_set_drvdata(pdev, NULL); - kfree(audio); - twl4030_audio_dev = NULL; - - return 0; -} - -MODULE_ALIAS("platform:twl4030-audio"); - -static struct platform_driver twl4030_audio_driver = { - .probe = twl4030_audio_probe, - .remove = __devexit_p(twl4030_audio_remove), - .driver = { - .owner = THIS_MODULE, - .name = "twl4030-audio", - }, -}; - -module_platform_driver(twl4030_audio_driver); - -MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl4030-irq.c b/ANDROID_3.4.5/drivers/mfd/twl4030-irq.c deleted file mode 100644 index 5d656e81..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl4030-irq.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * twl4030-irq.c - TWL4030/TPS659x0 irq support - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * Modifications to defer interrupt handling to a kernel thread: - * Copyright (C) 2006 MontaVista Software, Inc. - * - * Based on tlv320aic23.c: - * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> - * - * Code cleanup and modifications to IRQ handler. - * by syed khasim <x0khasim@ti.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <linux/of.h> -#include <linux/irqdomain.h> -#include <linux/i2c/twl.h> - -#include "twl-core.h" - -/* - * TWL4030 IRQ handling has two stages in hardware, and thus in software. - * The Primary Interrupt Handler (PIH) stage exposes status bits saying - * which Secondary Interrupt Handler (SIH) stage is raising an interrupt. - * SIH modules are more traditional IRQ components, which support per-IRQ - * enable/disable and trigger controls; they do most of the work. - * - * These chips are designed to support IRQ handling from two different - * I2C masters. Each has a dedicated IRQ line, and dedicated IRQ status - * and mask registers in the PIH and SIH modules. - * - * We set up IRQs starting at a platform-specified base, always starting - * with PIH and the SIH for PWR_INT and then usually adding GPIO: - * base + 0 .. base + 7 PIH - * base + 8 .. base + 15 SIH for PWR_INT - * base + 16 .. base + 33 SIH for GPIO - */ -#define TWL4030_CORE_NR_IRQS 8 -#define TWL4030_PWR_NR_IRQS 8 - -/* PIH register offsets */ -#define REG_PIH_ISR_P1 0x01 -#define REG_PIH_ISR_P2 0x02 -#define REG_PIH_SIR 0x03 /* for testing */ - -/* Linux could (eventually) use either IRQ line */ -static int irq_line; - -struct sih { - char name[8]; - u8 module; /* module id */ - u8 control_offset; /* for SIH_CTRL */ - bool set_cor; - - u8 bits; /* valid in isr/imr */ - u8 bytes_ixr; /* bytelen of ISR/IMR/SIR */ - - u8 edr_offset; - u8 bytes_edr; /* bytelen of EDR */ - - u8 irq_lines; /* number of supported irq lines */ - - /* SIR ignored -- set interrupt, for testing only */ - struct sih_irq_data { - u8 isr_offset; - u8 imr_offset; - } mask[2]; - /* + 2 bytes padding */ -}; - -static const struct sih *sih_modules; -static int nr_sih_modules; - -#define SIH_INITIALIZER(modname, nbits) \ - .module = TWL4030_MODULE_ ## modname, \ - .control_offset = TWL4030_ ## modname ## _SIH_CTRL, \ - .bits = nbits, \ - .bytes_ixr = DIV_ROUND_UP(nbits, 8), \ - .edr_offset = TWL4030_ ## modname ## _EDR, \ - .bytes_edr = DIV_ROUND_UP((2*(nbits)), 8), \ - .irq_lines = 2, \ - .mask = { { \ - .isr_offset = TWL4030_ ## modname ## _ISR1, \ - .imr_offset = TWL4030_ ## modname ## _IMR1, \ - }, \ - { \ - .isr_offset = TWL4030_ ## modname ## _ISR2, \ - .imr_offset = TWL4030_ ## modname ## _IMR2, \ - }, }, - -/* register naming policies are inconsistent ... */ -#define TWL4030_INT_PWR_EDR TWL4030_INT_PWR_EDR1 -#define TWL4030_MODULE_KEYPAD_KEYP TWL4030_MODULE_KEYPAD -#define TWL4030_MODULE_INT_PWR TWL4030_MODULE_INT - - -/* - * Order in this table matches order in PIH_ISR. That is, - * BIT(n) in PIH_ISR is sih_modules[n]. - */ -/* sih_modules_twl4030 is used both in twl4030 and twl5030 */ -static const struct sih sih_modules_twl4030[6] = { - [0] = { - .name = "gpio", - .module = TWL4030_MODULE_GPIO, - .control_offset = REG_GPIO_SIH_CTRL, - .set_cor = true, - .bits = TWL4030_GPIO_MAX, - .bytes_ixr = 3, - /* Note: *all* of these IRQs default to no-trigger */ - .edr_offset = REG_GPIO_EDR1, - .bytes_edr = 5, - .irq_lines = 2, - .mask = { { - .isr_offset = REG_GPIO_ISR1A, - .imr_offset = REG_GPIO_IMR1A, - }, { - .isr_offset = REG_GPIO_ISR1B, - .imr_offset = REG_GPIO_IMR1B, - }, }, - }, - [1] = { - .name = "keypad", - .set_cor = true, - SIH_INITIALIZER(KEYPAD_KEYP, 4) - }, - [2] = { - .name = "bci", - .module = TWL4030_MODULE_INTERRUPTS, - .control_offset = TWL4030_INTERRUPTS_BCISIHCTRL, - .set_cor = true, - .bits = 12, - .bytes_ixr = 2, - .edr_offset = TWL4030_INTERRUPTS_BCIEDR1, - /* Note: most of these IRQs default to no-trigger */ - .bytes_edr = 3, - .irq_lines = 2, - .mask = { { - .isr_offset = TWL4030_INTERRUPTS_BCIISR1A, - .imr_offset = TWL4030_INTERRUPTS_BCIIMR1A, - }, { - .isr_offset = TWL4030_INTERRUPTS_BCIISR1B, - .imr_offset = TWL4030_INTERRUPTS_BCIIMR1B, - }, }, - }, - [3] = { - .name = "madc", - SIH_INITIALIZER(MADC, 4) - }, - [4] = { - /* USB doesn't use the same SIH organization */ - .name = "usb", - }, - [5] = { - .name = "power", - .set_cor = true, - SIH_INITIALIZER(INT_PWR, 8) - }, - /* there are no SIH modules #6 or #7 ... */ -}; - -static const struct sih sih_modules_twl5031[8] = { - [0] = { - .name = "gpio", - .module = TWL4030_MODULE_GPIO, - .control_offset = REG_GPIO_SIH_CTRL, - .set_cor = true, - .bits = TWL4030_GPIO_MAX, - .bytes_ixr = 3, - /* Note: *all* of these IRQs default to no-trigger */ - .edr_offset = REG_GPIO_EDR1, - .bytes_edr = 5, - .irq_lines = 2, - .mask = { { - .isr_offset = REG_GPIO_ISR1A, - .imr_offset = REG_GPIO_IMR1A, - }, { - .isr_offset = REG_GPIO_ISR1B, - .imr_offset = REG_GPIO_IMR1B, - }, }, - }, - [1] = { - .name = "keypad", - .set_cor = true, - SIH_INITIALIZER(KEYPAD_KEYP, 4) - }, - [2] = { - .name = "bci", - .module = TWL5031_MODULE_INTERRUPTS, - .control_offset = TWL5031_INTERRUPTS_BCISIHCTRL, - .bits = 7, - .bytes_ixr = 1, - .edr_offset = TWL5031_INTERRUPTS_BCIEDR1, - /* Note: most of these IRQs default to no-trigger */ - .bytes_edr = 2, - .irq_lines = 2, - .mask = { { - .isr_offset = TWL5031_INTERRUPTS_BCIISR1, - .imr_offset = TWL5031_INTERRUPTS_BCIIMR1, - }, { - .isr_offset = TWL5031_INTERRUPTS_BCIISR2, - .imr_offset = TWL5031_INTERRUPTS_BCIIMR2, - }, }, - }, - [3] = { - .name = "madc", - SIH_INITIALIZER(MADC, 4) - }, - [4] = { - /* USB doesn't use the same SIH organization */ - .name = "usb", - }, - [5] = { - .name = "power", - .set_cor = true, - SIH_INITIALIZER(INT_PWR, 8) - }, - [6] = { - /* - * ECI/DBI doesn't use the same SIH organization. - * For example, it supports only one interrupt output line. - * That is, the interrupts are seen on both INT1 and INT2 lines. - */ - .name = "eci_dbi", - .module = TWL5031_MODULE_ACCESSORY, - .bits = 9, - .bytes_ixr = 2, - .irq_lines = 1, - .mask = { { - .isr_offset = TWL5031_ACIIDR_LSB, - .imr_offset = TWL5031_ACIIMR_LSB, - }, }, - - }, - [7] = { - /* Audio accessory */ - .name = "audio", - .module = TWL5031_MODULE_ACCESSORY, - .control_offset = TWL5031_ACCSIHCTRL, - .bits = 2, - .bytes_ixr = 1, - .edr_offset = TWL5031_ACCEDR1, - /* Note: most of these IRQs default to no-trigger */ - .bytes_edr = 1, - .irq_lines = 2, - .mask = { { - .isr_offset = TWL5031_ACCISR1, - .imr_offset = TWL5031_ACCIMR1, - }, { - .isr_offset = TWL5031_ACCISR2, - .imr_offset = TWL5031_ACCIMR2, - }, }, - }, -}; - -#undef TWL4030_MODULE_KEYPAD_KEYP -#undef TWL4030_MODULE_INT_PWR -#undef TWL4030_INT_PWR_EDR - -/*----------------------------------------------------------------------*/ - -static unsigned twl4030_irq_base; - -/* - * 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. - * Now we need to query the interrupt controller in the twl4030 to determine - * which module is generating the interrupt request. However, we can't do i2c - * transactions in interrupt context, so we must defer that work to a kernel - * thread. All we do here is acknowledge and mask the interrupt and wakeup - * the kernel thread. - */ -static irqreturn_t handle_twl4030_pih(int irq, void *devid) -{ - irqreturn_t ret; - 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; - } - - while (pih_isr) { - unsigned long pending = __ffs(pih_isr); - unsigned int irq; - - pih_isr &= ~BIT(pending); - irq = pending + twl4030_irq_base; - handle_nested_irq(irq); - } - - return IRQ_HANDLED; -} - -/*----------------------------------------------------------------------*/ - -/* - * twl4030_init_sih_modules() ... start from a known state where no - * IRQs will be coming in, and where we can quickly enable them then - * handle them as they arrive. Mask all IRQs: maybe init SIH_CTRL. - * - * NOTE: we don't touch EDR registers here; they stay with hardware - * defaults or whatever the last value was. Note that when both EDR - * bits for an IRQ are clear, that's as if its IMR bit is set... - */ -static int twl4030_init_sih_modules(unsigned line) -{ - const struct sih *sih; - u8 buf[4]; - int i; - int status; - - /* line 0 == int1_n signal; line 1 == int2_n signal */ - if (line > 1) - return -EINVAL; - - irq_line = line; - - /* disable all interrupts on our line */ - memset(buf, 0xff, sizeof buf); - sih = sih_modules; - for (i = 0; i < nr_sih_modules; i++, sih++) { - /* skip USB -- it's funky */ - if (!sih->bytes_ixr) - continue; - - /* Not all the SIH modules support multiple interrupt lines */ - if (sih->irq_lines <= line) - continue; - - status = twl_i2c_write(sih->module, buf, - sih->mask[line].imr_offset, sih->bytes_ixr); - if (status < 0) - pr_err("twl4030: err %d initializing %s %s\n", - status, sih->name, "IMR"); - - /* - * Maybe disable "exclusive" mode; buffer second pending irq; - * set Clear-On-Read (COR) bit. - * - * NOTE that sometimes COR polarity is documented as being - * inverted: for MADC, COR=1 means "clear on write". - * And for PWR_INT it's not documented... - */ - if (sih->set_cor) { - status = twl_i2c_write_u8(sih->module, - TWL4030_SIH_CTRL_COR_MASK, - sih->control_offset); - if (status < 0) - pr_err("twl4030: err %d initializing %s %s\n", - status, sih->name, "SIH_CTRL"); - } - } - - sih = sih_modules; - for (i = 0; i < nr_sih_modules; i++, sih++) { - u8 rxbuf[4]; - int j; - - /* skip USB */ - if (!sih->bytes_ixr) - continue; - - /* Not all the SIH modules support multiple interrupt lines */ - if (sih->irq_lines <= line) - continue; - - /* - * Clear pending interrupt status. Either the read was - * enough, or we need to write those bits. Repeat, in - * case an IRQ is pending (PENDDIS=0) ... that's not - * uncommon with PWR_INT.PWRON. - */ - for (j = 0; j < 2; j++) { - status = twl_i2c_read(sih->module, rxbuf, - sih->mask[line].isr_offset, sih->bytes_ixr); - if (status < 0) - pr_err("twl4030: err %d initializing %s %s\n", - status, sih->name, "ISR"); - - if (!sih->set_cor) - status = twl_i2c_write(sih->module, buf, - sih->mask[line].isr_offset, - sih->bytes_ixr); - /* - * else COR=1 means read sufficed. - * (for most SIH modules...) - */ - } - } - - return 0; -} - -static inline void activate_irq(int irq) -{ -#ifdef CONFIG_ARM - /* - * ARM requires an extra step to clear IRQ_NOREQUEST, which it - * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE. - */ - set_irq_flags(irq, IRQF_VALID); -#else - /* same effect on other architectures */ - irq_set_noprobe(irq); -#endif -} - -/*----------------------------------------------------------------------*/ - -struct sih_agent { - int irq_base; - const struct sih *sih; - - u32 imr; - bool imr_change_pending; - - u32 edge_change; - - struct mutex irq_lock; - char *irq_name; -}; - -/*----------------------------------------------------------------------*/ - -/* - * All irq_chip methods get issued from code holding irq_desc[irq].lock, - * which can't perform the underlying I2C operations (because they sleep). - * So we must hand them off to a thread (workqueue) and cope with asynch - * completion, potentially including some re-ordering, of these requests. - */ - -static void twl4030_sih_mask(struct irq_data *data) -{ - struct sih_agent *agent = irq_data_get_irq_chip_data(data); - - agent->imr |= BIT(data->irq - agent->irq_base); - agent->imr_change_pending = true; -} - -static void twl4030_sih_unmask(struct irq_data *data) -{ - struct sih_agent *agent = irq_data_get_irq_chip_data(data); - - agent->imr &= ~BIT(data->irq - agent->irq_base); - agent->imr_change_pending = true; -} - -static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) -{ - struct sih_agent *agent = irq_data_get_irq_chip_data(data); - - if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - return -EINVAL; - - if (irqd_get_trigger_type(data) != trigger) - agent->edge_change |= BIT(data->irq - agent->irq_base); - - 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 overwritten 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 = { - .name = "twl4030", - .irq_mask = twl4030_sih_mask, - .irq_unmask = twl4030_sih_unmask, - .irq_set_type = twl4030_sih_set_type, - .irq_bus_lock = twl4030_sih_bus_lock, - .irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock, -}; - -/*----------------------------------------------------------------------*/ - -static inline int sih_read_isr(const struct sih *sih) -{ - int status; - union { - u8 bytes[4]; - u32 word; - } isr; - - /* FIXME need retry-on-error ... */ - - isr.word = 0; - status = twl_i2c_read(sih->module, isr.bytes, - sih->mask[irq_line].isr_offset, sih->bytes_ixr); - - return (status < 0) ? status : le32_to_cpu(isr.word); -} - -/* - * Generic handler for SIH interrupts ... we "know" this is called - * in task context, with IRQs enabled. - */ -static irqreturn_t handle_twl4030_sih(int irq, void *data) -{ - struct sih_agent *agent = irq_get_handler_data(irq); - const struct sih *sih = agent->sih; - int isr; - - /* reading ISR acks the IRQs, using clear-on-read mode */ - isr = sih_read_isr(sih); - - if (isr < 0) { - pr_err("twl4030: %s SIH, read ISR error %d\n", - sih->name, isr); - /* REVISIT: recover; eventually mask it all, etc */ - return IRQ_HANDLED; - } - - while (isr) { - irq = fls(isr); - irq--; - isr &= ~BIT(irq); - - if (irq < sih->bits) - handle_nested_irq(agent->irq_base + irq); - else - pr_err("twl4030: %s SIH, invalid ISR bit %d\n", - sih->name, irq); - } - return IRQ_HANDLED; -} - -/* returns the first IRQ used by this SIH bank, or negative errno */ -int twl4030_sih_setup(struct device *dev, int module, int irq_base) -{ - int sih_mod; - const struct sih *sih = NULL; - struct sih_agent *agent; - int i, irq; - int status = -EINVAL; - - /* only support modules with standard clear-on-read for now */ - for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules; - sih_mod++, sih++) { - if (sih->module == module && sih->set_cor) { - status = 0; - break; - } - } - - if (status < 0) - return status; - - agent = kzalloc(sizeof *agent, GFP_KERNEL); - if (!agent) - return -ENOMEM; - - agent->irq_base = irq_base; - agent->sih = sih; - agent->imr = ~0; - mutex_init(&agent->irq_lock); - - for (i = 0; i < sih->bits; i++) { - irq = irq_base + i; - - irq_set_chip_data(irq, agent); - irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, - handle_edge_irq); - irq_set_nested_thread(irq, 1); - activate_irq(irq); - } - - /* replace generic PIH handler (handle_simple_irq) */ - irq = sih_mod + twl4030_irq_base; - irq_set_handler_data(irq, agent); - agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); - status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, - agent->irq_name ?: sih->name, NULL); - - dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, - irq, irq_base, irq_base + i - 1); - - return status < 0 ? status : irq_base; -} - -/* FIXME need a call to reverse twl4030_sih_setup() ... */ - -/*----------------------------------------------------------------------*/ - -/* FIXME pass in which interrupt line we'll use ... */ -#define twl_irq_line 0 - -int twl4030_init_irq(struct device *dev, int irq_num) -{ - static struct irq_chip twl4030_irq_chip; - int status, i; - int irq_base, irq_end, nr_irqs; - struct device_node *node = dev->of_node; - - /* - * TWL core and pwr interrupts must be contiguous because - * the hwirqs numbers are defined contiguously from 1 to 15. - * Create only one domain for both. - */ - nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS; - - irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); - if (IS_ERR_VALUE(irq_base)) { - dev_err(dev, "Fail to allocate IRQ descs\n"); - return irq_base; - } - - irq_domain_add_legacy(node, nr_irqs, irq_base, 0, - &irq_domain_simple_ops, NULL); - - irq_end = irq_base + TWL4030_CORE_NR_IRQS; - - /* - * Mask and clear all TWL4030 interrupts since initially we do - * not have any TWL4030 module interrupt handlers present - */ - status = twl4030_init_sih_modules(twl_irq_line); - if (status < 0) - return status; - - twl4030_irq_base = irq_base; - - /* - * Install an irq handler for each of the SIH modules; - * clone dummy irq_chip since PIH can't *do* anything - */ - twl4030_irq_chip = dummy_irq_chip; - twl4030_irq_chip.name = "twl4030"; - - twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; - - for (i = irq_base; i < irq_end; i++) { - irq_set_chip_and_handler(i, &twl4030_irq_chip, - handle_simple_irq); - irq_set_nested_thread(i, 1); - activate_irq(i); - } - - dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH", - irq_num, irq_base, irq_end); - - /* ... and the PWR_INT module ... */ - status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end); - if (status < 0) { - dev_err(dev, "sih_setup PWR INT --> %d\n", status); - goto fail; - } - - /* install an irq handler to demultiplex the TWL4030 interrupt */ - status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, - IRQF_ONESHOT, - "TWL4030-PIH", NULL); - if (status < 0) { - dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); - goto fail_rqirq; - } - - return irq_base; -fail_rqirq: - /* clean up twl4030_sih_setup */ -fail: - for (i = irq_base; i < irq_end; i++) { - irq_set_nested_thread(i, 0); - irq_set_chip_and_handler(i, NULL, NULL); - } - - return status; -} - -int twl4030_exit_irq(void) -{ - /* FIXME undo twl_init_irq() */ - if (twl4030_irq_base) { - pr_err("twl4030: can't yet clean up IRQs?\n"); - return -ENOSYS; - } - return 0; -} - -int twl4030_init_chip_irq(const char *chip) -{ - if (!strcmp(chip, "twl5031")) { - sih_modules = sih_modules_twl5031; - nr_sih_modules = ARRAY_SIZE(sih_modules_twl5031); - } else { - sih_modules = sih_modules_twl4030; - nr_sih_modules = ARRAY_SIZE(sih_modules_twl4030); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/twl4030-madc.c b/ANDROID_3.4.5/drivers/mfd/twl4030-madc.c deleted file mode 100644 index 456ecb5a..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl4030-madc.c +++ /dev/null @@ -1,815 +0,0 @@ -/* - * - * TWL4030 MADC module driver-This driver monitors the real time - * conversion of analog signals like battery temperature, - * battery type, battery level etc. - * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * J Keerthy <j-keerthy@ti.com> - * - * Based on twl4030-madc.c - * Copyright (C) 2008 Nokia Corporation - * Mikko Ylinen <mikko.k.ylinen@nokia.com> - * - * Amit Kucheria <amit.kucheria@canonical.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <linux/init.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/i2c/twl.h> -#include <linux/i2c/twl4030-madc.h> -#include <linux/module.h> -#include <linux/stddef.h> -#include <linux/mutex.h> -#include <linux/bitops.h> -#include <linux/jiffies.h> -#include <linux/types.h> -#include <linux/gfp.h> -#include <linux/err.h> - -/* - * struct twl4030_madc_data - a container for madc info - * @dev - pointer to device structure for madc - * @lock - mutex protecting this data structure - * @requests - Array of request struct corresponding to SW1, SW2 and RT - * @imr - Interrupt mask register of MADC - * @isr - Interrupt status register of MADC - */ -struct twl4030_madc_data { - struct device *dev; - struct mutex lock; /* mutex protecting this data structure */ - struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS]; - int imr; - int isr; -}; - -static struct twl4030_madc_data *twl4030_madc; - -struct twl4030_prescale_divider_ratios { - s16 numerator; - s16 denominator; -}; - -static const struct twl4030_prescale_divider_ratios -twl4030_divider_ratios[16] = { - {1, 1}, /* CHANNEL 0 No Prescaler */ - {1, 1}, /* CHANNEL 1 No Prescaler */ - {6, 10}, /* CHANNEL 2 */ - {6, 10}, /* CHANNEL 3 */ - {6, 10}, /* CHANNEL 4 */ - {6, 10}, /* CHANNEL 5 */ - {6, 10}, /* CHANNEL 6 */ - {6, 10}, /* CHANNEL 7 */ - {3, 14}, /* CHANNEL 8 */ - {1, 3}, /* CHANNEL 9 */ - {1, 1}, /* CHANNEL 10 No Prescaler */ - {15, 100}, /* CHANNEL 11 */ - {1, 4}, /* CHANNEL 12 */ - {1, 1}, /* CHANNEL 13 Reserved channels */ - {1, 1}, /* CHANNEL 14 Reseved channels */ - {5, 11}, /* CHANNEL 15 */ -}; - - -/* - * Conversion table from -3 to 55 degree Celcius - */ -static int therm_tbl[] = { -30800, 29500, 28300, 27100, -26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900, -17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100, -11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310, -8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830, -5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170, -4040, 3910, 3790, 3670, 3550 -}; - -/* - * Structure containing the registers - * of different conversion methods supported by MADC. - * Hardware or RT real time conversion request initiated by external host - * processor for RT Signal conversions. - * External host processors can also request for non RT conversions - * SW1 and SW2 software conversions also called asynchronous or GPC request. - */ -static -const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = { - [TWL4030_MADC_RT] = { - .sel = TWL4030_MADC_RTSELECT_LSB, - .avg = TWL4030_MADC_RTAVERAGE_LSB, - .rbase = TWL4030_MADC_RTCH0_LSB, - }, - [TWL4030_MADC_SW1] = { - .sel = TWL4030_MADC_SW1SELECT_LSB, - .avg = TWL4030_MADC_SW1AVERAGE_LSB, - .rbase = TWL4030_MADC_GPCH0_LSB, - .ctrl = TWL4030_MADC_CTRL_SW1, - }, - [TWL4030_MADC_SW2] = { - .sel = TWL4030_MADC_SW2SELECT_LSB, - .avg = TWL4030_MADC_SW2AVERAGE_LSB, - .rbase = TWL4030_MADC_GPCH0_LSB, - .ctrl = TWL4030_MADC_CTRL_SW2, - }, -}; - -/* - * Function to read a particular channel value. - * @madc - pointer to struct twl4030_madc_data - * @reg - lsb of ADC Channel - * If the i2c read fails it returns an error else returns 0. - */ -static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg) -{ - u8 msb, lsb; - int ret; - /* - * For each ADC channel, we have MSB and LSB register pair. MSB address - * is always LSB address+1. reg parameter is the address of LSB register - */ - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1); - if (ret) { - dev_err(madc->dev, "unable to read MSB register 0x%X\n", - reg + 1); - return ret; - } - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg); - if (ret) { - dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg); - return ret; - } - - return (int)(((msb << 8) | lsb) >> 6); -} - -/* - * Return battery temperature - * Or < 0 on failure. - */ -static int twl4030battery_temperature(int raw_volt) -{ - u8 val; - int temp, curr, volt, res, ret; - - volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R; - /* Getting and calculating the supply current in micro ampers */ - ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val, - REG_BCICTL2); - if (ret < 0) - return ret; - curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10; - /* Getting and calculating the thermistor resistance in ohms */ - res = volt * 1000 / curr; - /* calculating temperature */ - for (temp = 58; temp >= 0; temp--) { - int actual = therm_tbl[temp]; - - if ((actual - res) >= 0) - break; - } - - return temp + 1; -} - -static int twl4030battery_current(int raw_volt) -{ - int ret; - u8 val; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val, - TWL4030_BCI_BCICTL1); - if (ret) - return ret; - if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */ - return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1; - else /* slope of 0.88 mV/mA */ - return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2; -} -/* - * Function to read channel values - * @madc - pointer to twl4030_madc_data struct - * @reg_base - Base address of the first channel - * @Channels - 16 bit bitmap. If the bit is set, channel value is read - * @buf - The channel values are stored here. if read fails error - * value is stored - * Returns the number of successfully read channels. - */ -static int twl4030_madc_read_channels(struct twl4030_madc_data *madc, - u8 reg_base, unsigned - long channels, int *buf) -{ - int count = 0, count_req = 0, i; - u8 reg; - - for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) { - reg = reg_base + 2 * i; - buf[i] = twl4030_madc_channel_raw_read(madc, reg); - if (buf[i] < 0) { - dev_err(madc->dev, - "Unable to read register 0x%X\n", reg); - count_req++; - continue; - } - switch (i) { - case 10: - buf[i] = twl4030battery_current(buf[i]); - if (buf[i] < 0) { - dev_err(madc->dev, "err reading current\n"); - count_req++; - } else { - count++; - buf[i] = buf[i] - 750; - } - break; - case 1: - buf[i] = twl4030battery_temperature(buf[i]); - if (buf[i] < 0) { - dev_err(madc->dev, "err reading temperature\n"); - count_req++; - } else { - buf[i] -= 3; - count++; - } - break; - default: - count++; - /* Analog Input (V) = conv_result * step_size / R - * conv_result = decimal value of 10-bit conversion - * result - * step size = 1.5 / (2 ^ 10 -1) - * R = Prescaler ratio for input channels. - * Result given in mV hence multiplied by 1000. - */ - buf[i] = (buf[i] * 3 * 1000 * - twl4030_divider_ratios[i].denominator) - / (2 * 1023 * - twl4030_divider_ratios[i].numerator); - } - } - if (count_req) - dev_err(madc->dev, "%d channel conversion failed\n", count_req); - - return count; -} - -/* - * Enables irq. - * @madc - pointer to twl4030_madc_data struct - * @id - irq number to be enabled - * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2 - * corresponding to RT, SW1, SW2 conversion requests. - * If the i2c read fails it returns an error else returns 0. - */ -static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id) -{ - u8 val; - int ret; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr); - if (ret) { - dev_err(madc->dev, "unable to read imr register 0x%X\n", - madc->imr); - return ret; - } - val &= ~(1 << id); - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr); - if (ret) { - dev_err(madc->dev, - "unable to write imr register 0x%X\n", madc->imr); - return ret; - - } - - return 0; -} - -/* - * Disables irq. - * @madc - pointer to twl4030_madc_data struct - * @id - irq number to be disabled - * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2 - * corresponding to RT, SW1, SW2 conversion requests. - * Returns error if i2c read/write fails. - */ -static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id) -{ - u8 val; - int ret; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr); - if (ret) { - dev_err(madc->dev, "unable to read imr register 0x%X\n", - madc->imr); - return ret; - } - val |= (1 << id); - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr); - if (ret) { - dev_err(madc->dev, - "unable to write imr register 0x%X\n", madc->imr); - return ret; - } - - return 0; -} - -static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc) -{ - struct twl4030_madc_data *madc = _madc; - const struct twl4030_madc_conversion_method *method; - u8 isr_val, imr_val; - int i, len, ret; - struct twl4030_madc_request *r; - - mutex_lock(&madc->lock); - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr); - if (ret) { - dev_err(madc->dev, "unable to read isr register 0x%X\n", - madc->isr); - goto err_i2c; - } - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr); - if (ret) { - dev_err(madc->dev, "unable to read imr register 0x%X\n", - madc->imr); - goto err_i2c; - } - isr_val &= ~imr_val; - for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { - if (!(isr_val & (1 << i))) - continue; - ret = twl4030_madc_disable_irq(madc, i); - if (ret < 0) - dev_dbg(madc->dev, "Disable interrupt failed%d\n", i); - madc->requests[i].result_pending = 1; - } - for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { - r = &madc->requests[i]; - /* No pending results for this method, move to next one */ - if (!r->result_pending) - continue; - method = &twl4030_conversion_methods[r->method]; - /* Read results */ - len = twl4030_madc_read_channels(madc, method->rbase, - r->channels, r->rbuf); - /* Return results to caller */ - if (r->func_cb != NULL) { - r->func_cb(len, r->channels, r->rbuf); - r->func_cb = NULL; - } - /* Free request */ - r->result_pending = 0; - r->active = 0; - } - mutex_unlock(&madc->lock); - - return IRQ_HANDLED; - -err_i2c: - /* - * In case of error check whichever request is active - * and service the same. - */ - for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { - r = &madc->requests[i]; - if (r->active == 0) - continue; - method = &twl4030_conversion_methods[r->method]; - /* Read results */ - len = twl4030_madc_read_channels(madc, method->rbase, - r->channels, r->rbuf); - /* Return results to caller */ - if (r->func_cb != NULL) { - r->func_cb(len, r->channels, r->rbuf); - r->func_cb = NULL; - } - /* Free request */ - r->result_pending = 0; - r->active = 0; - } - mutex_unlock(&madc->lock); - - return IRQ_HANDLED; -} - -static int twl4030_madc_set_irq(struct twl4030_madc_data *madc, - struct twl4030_madc_request *req) -{ - struct twl4030_madc_request *p; - int ret; - - p = &madc->requests[req->method]; - memcpy(p, req, sizeof(*req)); - ret = twl4030_madc_enable_irq(madc, req->method); - if (ret < 0) { - dev_err(madc->dev, "enable irq failed!!\n"); - return ret; - } - - return 0; -} - -/* - * Function which enables the madc conversion - * by writing to the control register. - * @madc - pointer to twl4030_madc_data struct - * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1 - * corresponding to RT SW1 or SW2 conversion methods. - * Returns 0 if succeeds else a negative error value - */ -static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc, - int conv_method) -{ - const struct twl4030_madc_conversion_method *method; - int ret = 0; - method = &twl4030_conversion_methods[conv_method]; - switch (conv_method) { - case TWL4030_MADC_SW1: - case TWL4030_MADC_SW2: - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, - TWL4030_MADC_SW_START, method->ctrl); - if (ret) { - dev_err(madc->dev, - "unable to write ctrl register 0x%X\n", - method->ctrl); - return ret; - } - break; - default: - break; - } - - return 0; -} - -/* - * Function that waits for conversion to be ready - * @madc - pointer to twl4030_madc_data struct - * @timeout_ms - timeout value in milliseconds - * @status_reg - ctrl register - * returns 0 if succeeds else a negative error value - */ -static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc, - unsigned int timeout_ms, - u8 status_reg) -{ - unsigned long timeout; - int ret; - - timeout = jiffies + msecs_to_jiffies(timeout_ms); - do { - u8 reg; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, ®, status_reg); - if (ret) { - dev_err(madc->dev, - "unable to read status register 0x%X\n", - status_reg); - return ret; - } - if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW)) - return 0; - usleep_range(500, 2000); - } while (!time_after(jiffies, timeout)); - dev_err(madc->dev, "conversion timeout!\n"); - - return -EAGAIN; -} - -/* - * An exported function which can be called from other kernel drivers. - * @req twl4030_madc_request structure - * req->rbuf will be filled with read values of channels based on the - * channel index. If a particular channel reading fails there will - * be a negative error value in the corresponding array element. - * returns 0 if succeeds else error value - */ -int twl4030_madc_conversion(struct twl4030_madc_request *req) -{ - const struct twl4030_madc_conversion_method *method; - u8 ch_msb, ch_lsb; - int ret; - - if (!req || !twl4030_madc) - return -EINVAL; - - mutex_lock(&twl4030_madc->lock); - if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) { - ret = -EINVAL; - goto out; - } - /* Do we have a conversion request ongoing */ - if (twl4030_madc->requests[req->method].active) { - ret = -EBUSY; - goto out; - } - ch_msb = (req->channels >> 8) & 0xff; - ch_lsb = req->channels & 0xff; - method = &twl4030_conversion_methods[req->method]; - /* Select channels to be converted */ - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1); - if (ret) { - dev_err(twl4030_madc->dev, - "unable to write sel register 0x%X\n", method->sel + 1); - goto out; - } - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel); - if (ret) { - dev_err(twl4030_madc->dev, - "unable to write sel register 0x%X\n", method->sel + 1); - goto out; - } - /* Select averaging for all channels if do_avg is set */ - if (req->do_avg) { - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, - ch_msb, method->avg + 1); - if (ret) { - dev_err(twl4030_madc->dev, - "unable to write avg register 0x%X\n", - method->avg + 1); - goto out; - } - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, - ch_lsb, method->avg); - if (ret) { - dev_err(twl4030_madc->dev, - "unable to write sel reg 0x%X\n", - method->sel + 1); - goto out; - } - } - if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) { - ret = twl4030_madc_set_irq(twl4030_madc, req); - if (ret < 0) - goto out; - ret = twl4030_madc_start_conversion(twl4030_madc, req->method); - if (ret < 0) - goto out; - twl4030_madc->requests[req->method].active = 1; - ret = 0; - goto out; - } - /* With RT method we should not be here anymore */ - if (req->method == TWL4030_MADC_RT) { - ret = -EINVAL; - goto out; - } - ret = twl4030_madc_start_conversion(twl4030_madc, req->method); - if (ret < 0) - goto out; - twl4030_madc->requests[req->method].active = 1; - /* Wait until conversion is ready (ctrl register returns EOC) */ - ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl); - if (ret) { - twl4030_madc->requests[req->method].active = 0; - goto out; - } - ret = twl4030_madc_read_channels(twl4030_madc, method->rbase, - req->channels, req->rbuf); - twl4030_madc->requests[req->method].active = 0; - -out: - mutex_unlock(&twl4030_madc->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(twl4030_madc_conversion); - -/* - * Return channel value - * Or < 0 on failure. - */ -int twl4030_get_madc_conversion(int channel_no) -{ - struct twl4030_madc_request req; - int temp = 0; - int ret; - - req.channels = (1 << channel_no); - req.method = TWL4030_MADC_SW2; - req.active = 0; - req.func_cb = NULL; - ret = twl4030_madc_conversion(&req); - if (ret < 0) - return ret; - if (req.rbuf[channel_no] > 0) - temp = req.rbuf[channel_no]; - - return temp; -} -EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion); - -/* - * Function to enable or disable bias current for - * main battery type reading or temperature sensing - * @madc - pointer to twl4030_madc_data struct - * @chan - can be one of the two values - * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading - * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature - * sensing - * @on - enable or disable chan. - */ -static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc, - int chan, int on) -{ - int ret; - u8 regval; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, - ®val, TWL4030_BCI_BCICTL1); - if (ret) { - dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X", - TWL4030_BCI_BCICTL1); - return ret; - } - if (on) - regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN; - else - regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN; - ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, - regval, TWL4030_BCI_BCICTL1); - if (ret) { - dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n", - TWL4030_BCI_BCICTL1); - return ret; - } - - return 0; -} - -/* - * Function that sets MADC software power on bit to enable MADC - * @madc - pointer to twl4030_madc_data struct - * @on - Enable or disable MADC software powen on bit. - * returns error if i2c read/write fails else 0 - */ -static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on) -{ - u8 regval; - int ret; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, - ®val, TWL4030_MADC_CTRL1); - if (ret) { - dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n", - TWL4030_MADC_CTRL1); - return ret; - } - if (on) - regval |= TWL4030_MADC_MADCON; - else - regval &= ~TWL4030_MADC_MADCON; - ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1); - if (ret) { - dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n", - TWL4030_MADC_CTRL1); - return ret; - } - - return 0; -} - -/* - * Initialize MADC and request for threaded irq - */ -static int __devinit twl4030_madc_probe(struct platform_device *pdev) -{ - struct twl4030_madc_data *madc; - struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data; - int ret; - u8 regval; - - if (!pdata) { - dev_err(&pdev->dev, "platform_data not available\n"); - return -EINVAL; - } - madc = kzalloc(sizeof(*madc), GFP_KERNEL); - if (!madc) - return -ENOMEM; - - madc->dev = &pdev->dev; - - /* - * Phoenix provides 2 interrupt lines. The first one is connected to - * the OMAP. The other one can be connected to the other processor such - * as modem. Hence two separate ISR and IMR registers. - */ - madc->imr = (pdata->irq_line == 1) ? - TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2; - madc->isr = (pdata->irq_line == 1) ? - TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2; - ret = twl4030_madc_set_power(madc, 1); - if (ret < 0) - goto err_power; - ret = twl4030_madc_set_current_generator(madc, 0, 1); - if (ret < 0) - goto err_current_generator; - - ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, - ®val, TWL4030_BCI_BCICTL1); - if (ret) { - dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n", - TWL4030_BCI_BCICTL1); - goto err_i2c; - } - regval |= TWL4030_BCI_MESBAT; - ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, - regval, TWL4030_BCI_BCICTL1); - if (ret) { - dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n", - TWL4030_BCI_BCICTL1); - 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); - mutex_init(&madc->lock); - ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL, - twl4030_madc_threaded_irq_handler, - IRQF_TRIGGER_RISING, "twl4030_madc", madc); - if (ret) { - dev_dbg(&pdev->dev, "could not request irq\n"); - goto err_irq; - } - twl4030_madc = madc; - return 0; -err_irq: - platform_set_drvdata(pdev, NULL); -err_i2c: - twl4030_madc_set_current_generator(madc, 0, 0); -err_current_generator: - twl4030_madc_set_power(madc, 0); -err_power: - kfree(madc); - - return ret; -} - -static int __devexit twl4030_madc_remove(struct platform_device *pdev) -{ - struct twl4030_madc_data *madc = platform_get_drvdata(pdev); - - free_irq(platform_get_irq(pdev, 0), madc); - platform_set_drvdata(pdev, NULL); - twl4030_madc_set_current_generator(madc, 0, 0); - twl4030_madc_set_power(madc, 0); - kfree(madc); - - return 0; -} - -static struct platform_driver twl4030_madc_driver = { - .probe = twl4030_madc_probe, - .remove = __exit_p(twl4030_madc_remove), - .driver = { - .name = "twl4030_madc", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(twl4030_madc_driver); - -MODULE_DESCRIPTION("TWL4030 ADC driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("J Keerthy"); -MODULE_ALIAS("platform:twl4030_madc"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl4030-power.c b/ANDROID_3.4.5/drivers/mfd/twl4030-power.c deleted file mode 100644 index 79ca33df..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl4030-power.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * linux/drivers/i2c/chips/twl4030-power.c - * - * Handle TWL4030 Power initialization - * - * Copyright (C) 2008 Nokia Corporation - * Copyright (C) 2006 Texas Instruments, Inc - * - * Written by Kalle Jokiniemi - * Peter De Schrijver <peter.de-schrijver@nokia.com> - * Several fixes by Amit Kucheria <amit.kucheria@verdurent.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/module.h> -#include <linux/pm.h> -#include <linux/i2c/twl.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> - -static u8 twl4030_start_script_address = 0x2b; - -#define PWR_P1_SW_EVENTS 0x10 -#define PWR_DEVOFF (1 << 0) -#define SEQ_OFFSYNC (1 << 0) - -#define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) -#define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) - -/* resource - hfclk */ -#define R_HFCLKOUT_DEV_GRP PHY_TO_OFF_PM_RECEIVER(0xe6) - -/* PM events */ -#define R_P1_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x46) -#define R_P2_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x47) -#define R_P3_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x48) -#define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36) -#define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) -#define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) - -#define LVL_WAKEUP 0x08 - -#define ENABLE_WARMRESET (1<<4) - -#define END_OF_SCRIPT 0x3f - -#define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) -#define R_SEQ_ADD_S2A12 PHY_TO_OFF_PM_MASTER(0x56) -#define R_SEQ_ADD_S2A3 PHY_TO_OFF_PM_MASTER(0x57) -#define R_SEQ_ADD_WARM PHY_TO_OFF_PM_MASTER(0x58) -#define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59) -#define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a) - -/* resource configuration registers - <RESOURCE>_DEV_GRP at address 'n+0' - <RESOURCE>_TYPE at address 'n+1' - <RESOURCE>_REMAP at address 'n+2' - <RESOURCE>_DEDICATED at address 'n+3' -*/ -#define DEV_GRP_OFFSET 0 -#define TYPE_OFFSET 1 -#define REMAP_OFFSET 2 -#define DEDICATED_OFFSET 3 - -/* Bit positions in the registers */ - -/* <RESOURCE>_DEV_GRP */ -#define DEV_GRP_SHIFT 5 -#define DEV_GRP_MASK (7 << DEV_GRP_SHIFT) - -/* <RESOURCE>_TYPE */ -#define TYPE_SHIFT 0 -#define TYPE_MASK (7 << TYPE_SHIFT) -#define TYPE2_SHIFT 3 -#define TYPE2_MASK (3 << TYPE2_SHIFT) - -/* <RESOURCE>_REMAP */ -#define SLEEP_STATE_SHIFT 0 -#define SLEEP_STATE_MASK (0xf << SLEEP_STATE_SHIFT) -#define OFF_STATE_SHIFT 4 -#define OFF_STATE_MASK (0xf << OFF_STATE_SHIFT) - -static u8 res_config_addrs[] = { - [RES_VAUX1] = 0x17, - [RES_VAUX2] = 0x1b, - [RES_VAUX3] = 0x1f, - [RES_VAUX4] = 0x23, - [RES_VMMC1] = 0x27, - [RES_VMMC2] = 0x2b, - [RES_VPLL1] = 0x2f, - [RES_VPLL2] = 0x33, - [RES_VSIM] = 0x37, - [RES_VDAC] = 0x3b, - [RES_VINTANA1] = 0x3f, - [RES_VINTANA2] = 0x43, - [RES_VINTDIG] = 0x47, - [RES_VIO] = 0x4b, - [RES_VDD1] = 0x55, - [RES_VDD2] = 0x63, - [RES_VUSB_1V5] = 0x71, - [RES_VUSB_1V8] = 0x74, - [RES_VUSB_3V1] = 0x77, - [RES_VUSBCP] = 0x7a, - [RES_REGEN] = 0x7f, - [RES_NRES_PWRON] = 0x82, - [RES_CLKEN] = 0x85, - [RES_SYSEN] = 0x88, - [RES_HFCLKOUT] = 0x8b, - [RES_32KCLKOUT] = 0x8e, - [RES_RESET] = 0x91, - [RES_MAIN_REF] = 0x94, -}; - -static int __devinit twl4030_write_script_byte(u8 address, u8 byte) -{ - int err; - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address, - R_MEMORY_ADDRESS); - if (err) - goto out; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, byte, - R_MEMORY_DATA); -out: - return err; -} - -static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message, - u8 delay, u8 next) -{ - int err; - - address *= 4; - err = twl4030_write_script_byte(address++, pmb_message >> 8); - if (err) - goto out; - err = twl4030_write_script_byte(address++, pmb_message & 0xff); - if (err) - goto out; - err = twl4030_write_script_byte(address++, delay); - if (err) - goto out; - err = twl4030_write_script_byte(address++, next); -out: - return err; -} - -static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script, - int len) -{ - int err; - - for (; len; len--, address++, script++) { - if (len == 1) { - err = twl4030_write_script_ins(address, - script->pmb_message, - script->delay, - END_OF_SCRIPT); - if (err) - break; - } else { - err = twl4030_write_script_ins(address, - script->pmb_message, - script->delay, - address + 1); - if (err) - break; - } - } - return err; -} - -static int __devinit twl4030_config_wakeup3_sequence(u8 address) -{ - int err; - u8 data; - - /* Set SLEEP to ACTIVE SEQ address for P3 */ - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address, - R_SEQ_ADD_S2A3); - if (err) - goto out; - - /* P3 LVL_WAKEUP should be on LEVEL */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data, - R_P3_SW_EVENTS); - if (err) - goto out; - data |= LVL_WAKEUP; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data, - R_P3_SW_EVENTS); -out: - if (err) - pr_err("TWL4030 wakeup sequence for P3 config error\n"); - return err; -} - -static int __devinit twl4030_config_wakeup12_sequence(u8 address) -{ - int err = 0; - u8 data; - - /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */ - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address, - R_SEQ_ADD_S2A12); - if (err) - goto out; - - /* P1/P2 LVL_WAKEUP should be on LEVEL */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data, - R_P1_SW_EVENTS); - if (err) - goto out; - - data |= LVL_WAKEUP; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data, - R_P1_SW_EVENTS); - if (err) - goto out; - - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data, - R_P2_SW_EVENTS); - if (err) - goto out; - - data |= LVL_WAKEUP; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data, - R_P2_SW_EVENTS); - if (err) - goto out; - - if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) { - /* Disabling AC charger effect on sleep-active transitions */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data, - R_CFG_P1_TRANSITION); - if (err) - goto out; - data &= ~(1<<1); - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data , - R_CFG_P1_TRANSITION); - if (err) - goto out; - } - -out: - if (err) - pr_err("TWL4030 wakeup sequence for P1 and P2" \ - "config error\n"); - return err; -} - -static int __devinit twl4030_config_sleep_sequence(u8 address) -{ - int err; - - /* Set ACTIVE to SLEEP SEQ address in T2 memory*/ - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address, - R_SEQ_ADD_A2S); - - if (err) - pr_err("TWL4030 sleep sequence config error\n"); - - return err; -} - -static int __devinit twl4030_config_warmreset_sequence(u8 address) -{ - int err; - u8 rd_data; - - /* Set WARM RESET SEQ address for P1 */ - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address, - R_SEQ_ADD_WARM); - if (err) - goto out; - - /* P1/P2/P3 enable WARMRESET */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data, - R_P1_SW_EVENTS); - if (err) - goto out; - - rd_data |= ENABLE_WARMRESET; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data, - R_P1_SW_EVENTS); - if (err) - goto out; - - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data, - R_P2_SW_EVENTS); - if (err) - goto out; - - rd_data |= ENABLE_WARMRESET; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data, - R_P2_SW_EVENTS); - if (err) - goto out; - - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data, - R_P3_SW_EVENTS); - if (err) - goto out; - - rd_data |= ENABLE_WARMRESET; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data, - R_P3_SW_EVENTS); -out: - if (err) - pr_err("TWL4030 warmreset seq config error\n"); - return err; -} - -static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig) -{ - int rconfig_addr; - int err; - u8 type; - u8 grp; - u8 remap; - - if (rconfig->resource > TOTAL_RESOURCES) { - pr_err("TWL4030 Resource %d does not exist\n", - rconfig->resource); - return -EINVAL; - } - - rconfig_addr = res_config_addrs[rconfig->resource]; - - /* Set resource group */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp, - rconfig_addr + DEV_GRP_OFFSET); - if (err) { - pr_err("TWL4030 Resource %d group could not be read\n", - rconfig->resource); - return err; - } - - if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { - grp &= ~DEV_GRP_MASK; - grp |= rconfig->devgroup << DEV_GRP_SHIFT; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - grp, rconfig_addr + DEV_GRP_OFFSET); - if (err < 0) { - pr_err("TWL4030 failed to program devgroup\n"); - return err; - } - } - - /* Set resource types */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type, - rconfig_addr + TYPE_OFFSET); - if (err < 0) { - pr_err("TWL4030 Resource %d type could not be read\n", - rconfig->resource); - return err; - } - - if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { - type &= ~TYPE_MASK; - type |= rconfig->type << TYPE_SHIFT; - } - - if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { - type &= ~TYPE2_MASK; - type |= rconfig->type2 << TYPE2_SHIFT; - } - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - type, rconfig_addr + TYPE_OFFSET); - if (err < 0) { - pr_err("TWL4030 failed to program resource type\n"); - return err; - } - - /* Set remap states */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap, - rconfig_addr + REMAP_OFFSET); - if (err < 0) { - pr_err("TWL4030 Resource %d remap could not be read\n", - rconfig->resource); - return err; - } - - if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { - remap &= ~OFF_STATE_MASK; - remap |= rconfig->remap_off << OFF_STATE_SHIFT; - } - - if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { - remap &= ~SLEEP_STATE_MASK; - remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; - } - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - remap, - rconfig_addr + REMAP_OFFSET); - if (err < 0) { - pr_err("TWL4030 failed to program remap\n"); - return err; - } - - return 0; -} - -static int __devinit load_twl4030_script(struct twl4030_script *tscript, - u8 address) -{ - int err; - static int order; - - /* Make sure the script isn't going beyond last valid address (0x3f) */ - if ((address + tscript->size) > END_OF_SCRIPT) { - pr_err("TWL4030 scripts too big error\n"); - return -EINVAL; - } - - err = twl4030_write_script(address, tscript->script, tscript->size); - if (err) - goto out; - - if (tscript->flags & TWL4030_WRST_SCRIPT) { - err = twl4030_config_warmreset_sequence(address); - if (err) - goto out; - } - if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { - err = twl4030_config_wakeup12_sequence(address); - if (err) - goto out; - order = 1; - } - if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) { - err = twl4030_config_wakeup3_sequence(address); - if (err) - goto out; - } - if (tscript->flags & TWL4030_SLEEP_SCRIPT) { - if (!order) - pr_warning("TWL4030: Bad order of scripts (sleep "\ - "script before wakeup) Leads to boot"\ - "failure on some boards\n"); - err = twl4030_config_sleep_sequence(address); - } -out: - return err; -} - -int twl4030_remove_script(u8 flags) -{ - int err = 0; - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) { - pr_err("twl4030: unable to unlock PROTECT_KEY\n"); - return err; - } - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) { - pr_err("twl4030: unable to unlock PROTECT_KEY\n"); - return err; - } - - if (flags & TWL4030_WRST_SCRIPT) { - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, - R_SEQ_ADD_WARM); - if (err) - return err; - } - if (flags & TWL4030_WAKEUP12_SCRIPT) { - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, - R_SEQ_ADD_S2A12); - if (err) - return err; - } - if (flags & TWL4030_WAKEUP3_SCRIPT) { - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, - R_SEQ_ADD_S2A3); - if (err) - return err; - } - if (flags & TWL4030_SLEEP_SCRIPT) { - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT, - R_SEQ_ADD_A2S); - if (err) - return err; - } - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - pr_err("TWL4030 Unable to relock registers\n"); - - return err; -} - -/* - * In master mode, start the power off sequence. - * After a successful execution, TWL shuts down the power to the SoC - * and all peripherals connected to it. - */ -void twl4030_power_off(void) -{ - int err; - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, PWR_DEVOFF, - TWL4030_PM_MASTER_P1_SW_EVENTS); - if (err) - pr_err("TWL4030 Unable to power off\n"); -} - -void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts) -{ - int err = 0; - int i; - struct twl4030_resconfig *resconfig; - u8 val, address = twl4030_start_script_address; - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - goto unlock; - - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - goto unlock; - - for (i = 0; i < twl4030_scripts->num; i++) { - err = load_twl4030_script(twl4030_scripts->scripts[i], address); - if (err) - goto load; - address += twl4030_scripts->scripts[i]->size; - } - - resconfig = twl4030_scripts->resource_config; - if (resconfig) { - while (resconfig->resource) { - err = twl4030_configure_resource(resconfig); - if (err) - goto resource; - resconfig++; - - } - } - - /* Board has to be wired properly to use this feature */ - if (twl4030_scripts->use_poweroff && !pm_power_off) { - /* Default for SEQ_OFFSYNC is set, lets ensure this */ - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val, - TWL4030_PM_MASTER_CFG_P123_TRANSITION); - if (err) { - pr_warning("TWL4030 Unable to read registers\n"); - - } else if (!(val & SEQ_OFFSYNC)) { - val |= SEQ_OFFSYNC; - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val, - TWL4030_PM_MASTER_CFG_P123_TRANSITION); - if (err) { - pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); - goto relock; - } - } - - pm_power_off = twl4030_power_off; - } - -relock: - err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - pr_err("TWL4030 Unable to relock registers\n"); - return; - -unlock: - if (err) - pr_err("TWL4030 Unable to unlock registers\n"); - return; -load: - if (err) - pr_err("TWL4030 failed to load scripts\n"); - return; -resource: - if (err) - pr_err("TWL4030 failed to configure resource\n"); - return; -} diff --git a/ANDROID_3.4.5/drivers/mfd/twl6030-irq.c b/ANDROID_3.4.5/drivers/mfd/twl6030-irq.c deleted file mode 100644 index b76902f1..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl6030-irq.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * twl6030-irq.c - TWL6030 irq support - * - * Copyright (C) 2005-2009 Texas Instruments, Inc. - * - * Modifications to defer interrupt handling to a kernel thread: - * Copyright (C) 2006 MontaVista Software, Inc. - * - * Based on tlv320aic23.c: - * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> - * - * Code cleanup and modifications to IRQ handler. - * by syed khasim <x0khasim@ti.com> - * - * TWL6030 specific code and IRQ handling changes by - * Jagadeesh Bhaskar Pakaravoor <j-pakaravoor@ti.com> - * Balaji T K <balajitk@ti.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kthread.h> -#include <linux/i2c/twl.h> -#include <linux/platform_device.h> -#include <linux/suspend.h> -#include <linux/of.h> -#include <linux/irqdomain.h> - -#include "twl-core.h" - -/* - * TWL6030 (unlike its predecessors, which had two level interrupt handling) - * three interrupt registers INT_STS_A, INT_STS_B and INT_STS_C. - * It exposes status bits saying who has raised an interrupt. There are - * three mask registers that corresponds to these status registers, that - * enables/disables these interrupts. - * - * We set up IRQs starting at a platform-specified base. An interrupt map table, - * specifies mapping between interrupt number and the associated module. - */ -#define TWL6030_NR_IRQS 20 - -static int twl6030_interrupt_mapping[24] = { - PWR_INTR_OFFSET, /* Bit 0 PWRON */ - PWR_INTR_OFFSET, /* Bit 1 RPWRON */ - PWR_INTR_OFFSET, /* Bit 2 BAT_VLOW */ - RTC_INTR_OFFSET, /* Bit 3 RTC_ALARM */ - RTC_INTR_OFFSET, /* Bit 4 RTC_PERIOD */ - HOTDIE_INTR_OFFSET, /* Bit 5 HOT_DIE */ - SMPSLDO_INTR_OFFSET, /* Bit 6 VXXX_SHORT */ - SMPSLDO_INTR_OFFSET, /* Bit 7 VMMC_SHORT */ - - SMPSLDO_INTR_OFFSET, /* Bit 8 VUSIM_SHORT */ - BATDETECT_INTR_OFFSET, /* Bit 9 BAT */ - SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ - MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ - RSV_INTR_OFFSET, /* Bit 12 Reserved */ - MADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */ - MADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */ - GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ - - USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ - USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ - USBOTG_INTR_OFFSET, /* Bit 18 ID */ - USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ - CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ - CHARGERFAULT_INTR_OFFSET, /* Bit 21 EXT_CHRG */ - CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ - RSV_INTR_OFFSET, /* Bit 23 Reserved */ -}; -/*----------------------------------------------------------------------*/ - -static unsigned twl6030_irq_base; -static int twl_irq; -static bool twl_irq_wake_enabled; - -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. - */ -static int twl6030_irq_thread(void *data) -{ - long irq = (long)data; - static unsigned i2c_errors; - static const unsigned max_i2c_errors = 100; - int ret; - - while (!kthread_should_stop()) { - int i; - union { - u8 bytes[4]; - u32 int_sts; - } sts; - - /* Wait for IRQ, then read PIH irq status (also blocking) */ - wait_for_completion_interruptible(&irq_event); - - /* read INT_STS_A, B and C in one shot using a burst read */ - ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes, - REG_INT_STS_A, 3); - if (ret) { - pr_warning("twl6030: I2C error %d reading PIH ISR\n", - ret); - if (++i2c_errors >= max_i2c_errors) { - printk(KERN_ERR "Maximum I2C error count" - " exceeded. Terminating %s.\n", - __func__); - break; - } - complete(&irq_event); - continue; - } - - - - sts.bytes[3] = 0; /* Only 24 bits are valid*/ - - /* - * Since VBUS status bit is not reliable for VBUS disconnect - * use CHARGER VBUS detection status bit instead. - */ - if (sts.bytes[2] & 0x10) - sts.bytes[2] |= 0x08; - - for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { - local_irq_disable(); - if (sts.int_sts & 0x1) { - int module_irq = twl6030_irq_base + - twl6030_interrupt_mapping[i]; - generic_handle_irq(module_irq); - - } - local_irq_enable(); - } - - /* - * NOTE: - * Simulation confirms that documentation is wrong w.r.t the - * interrupt status clear operation. A single *byte* write to - * any one of STS_A to STS_C register results in all three - * STS registers being reset. Since it does not matter which - * value is written, all three registers are cleared on a - * single byte write, so we just use 0x0 to clear. - */ - ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A); - if (ret) - pr_warning("twl6030: I2C error in clearing PIH ISR\n"); - - enable_irq(irq); - } - - return 0; -} - -/* - * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt. - * This is a chained interrupt, so there is no desc->action method for it. - * Now we need to query the interrupt controller in the twl6030 to determine - * which module is generating the interrupt request. However, we can't do i2c - * transactions in interrupt context, so we must defer that work to a kernel - * thread. All we do here is acknowledge and mask the interrupt and wakeup - * the kernel thread. - */ -static irqreturn_t handle_twl6030_pih(int irq, void *devid) -{ - disable_irq_nosync(irq); - complete(devid); - return IRQ_HANDLED; -} - -/*----------------------------------------------------------------------*/ - -static inline void activate_irq(int irq) -{ -#ifdef CONFIG_ARM - /* ARM requires an extra step to clear IRQ_NOREQUEST, which it - * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE. - */ - set_irq_flags(irq, IRQF_VALID); -#else - /* same effect on other architectures */ - irq_set_noprobe(irq); -#endif -} - -static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) -{ - if (on) - atomic_inc(&twl6030_wakeirqs); - else - atomic_dec(&twl6030_wakeirqs); - - return 0; -} - -int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) -{ - int ret; - u8 unmask_value; - ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value, - REG_INT_STS_A + offset); - unmask_value &= (~(bit_mask)); - ret |= twl_i2c_write_u8(TWL_MODULE_PIH, unmask_value, - REG_INT_STS_A + offset); /* unmask INT_MSK_A/B/C */ - return ret; -} -EXPORT_SYMBOL(twl6030_interrupt_unmask); - -int twl6030_interrupt_mask(u8 bit_mask, u8 offset) -{ - int ret; - u8 mask_value; - ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value, - REG_INT_STS_A + offset); - mask_value |= (bit_mask); - ret |= twl_i2c_write_u8(TWL_MODULE_PIH, mask_value, - REG_INT_STS_A + offset); /* mask INT_MSK_A/B/C */ - return ret; -} -EXPORT_SYMBOL(twl6030_interrupt_mask); - -int twl6030_mmc_card_detect_config(void) -{ - int ret; - u8 reg_val = 0; - - /* Unmasking the Card detect Interrupt line for MMC1 from Phoenix */ - twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, - REG_INT_MSK_LINE_B); - twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, - REG_INT_MSK_STS_B); - /* - * Initially Configuring MMC_CTRL for receiving interrupts & - * Card status on TWL6030 for MMC1 - */ - ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, TWL6030_MMCCTRL); - if (ret < 0) { - pr_err("twl6030: Failed to read MMCCTRL, error %d\n", ret); - return ret; - } - reg_val &= ~VMMC_AUTO_OFF; - reg_val |= SW_FC; - ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, TWL6030_MMCCTRL); - if (ret < 0) { - pr_err("twl6030: Failed to write MMCCTRL, error %d\n", ret); - return ret; - } - - /* Configuring PullUp-PullDown register */ - ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, - TWL6030_CFG_INPUT_PUPD3); - if (ret < 0) { - pr_err("twl6030: Failed to read CFG_INPUT_PUPD3, error %d\n", - ret); - return ret; - } - reg_val &= ~(MMC_PU | MMC_PD); - ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, - TWL6030_CFG_INPUT_PUPD3); - if (ret < 0) { - pr_err("twl6030: Failed to write CFG_INPUT_PUPD3, error %d\n", - ret); - return ret; - } - - return twl6030_irq_base + MMCDETECT_INTR_OFFSET; -} -EXPORT_SYMBOL(twl6030_mmc_card_detect_config); - -int twl6030_mmc_card_detect(struct device *dev, int slot) -{ - int ret = -EIO; - u8 read_reg = 0; - struct platform_device *pdev = to_platform_device(dev); - - if (pdev->id) { - /* TWL6030 provide's Card detect support for - * only MMC1 controller. - */ - pr_err("Unknown MMC controller %d in %s\n", pdev->id, __func__); - return ret; - } - /* - * BIT0 of MMC_CTRL on TWL6030 provides card status for MMC1 - * 0 - Card not present ,1 - Card present - */ - ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, &read_reg, - TWL6030_MMCCTRL); - if (ret >= 0) - ret = read_reg & STS_MMC; - return ret; -} -EXPORT_SYMBOL(twl6030_mmc_card_detect); - -int twl6030_init_irq(struct device *dev, int irq_num) -{ - struct device_node *node = dev->of_node; - int nr_irqs, irq_base, irq_end; - struct task_struct *task; - static struct irq_chip twl6030_irq_chip; - int status = 0; - int i; - u8 mask[4]; - - nr_irqs = TWL6030_NR_IRQS; - - irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); - if (IS_ERR_VALUE(irq_base)) { - dev_err(dev, "Fail to allocate IRQ descs\n"); - return irq_base; - } - - irq_domain_add_legacy(node, nr_irqs, irq_base, 0, - &irq_domain_simple_ops, NULL); - - irq_end = irq_base + nr_irqs; - - mask[1] = 0xFF; - mask[2] = 0xFF; - mask[3] = 0xFF; - - /* mask all int lines */ - twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); - /* mask all int sts */ - twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); - /* clear INT_STS_A,B,C */ - twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); - - twl6030_irq_base = irq_base; - - /* - * install an irq handler for each of the modules; - * clone dummy irq_chip since PIH can't *do* anything - */ - twl6030_irq_chip = dummy_irq_chip; - twl6030_irq_chip.name = "twl6030"; - twl6030_irq_chip.irq_set_type = NULL; - twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; - - for (i = irq_base; i < irq_end; i++) { - irq_set_chip_and_handler(i, &twl6030_irq_chip, - handle_simple_irq); - irq_set_chip_data(i, (void *)irq_num); - activate_irq(i); - } - - dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n", - irq_num, irq_base, irq_end); - - /* install an irq handler to demultiplex the TWL6030 interrupt */ - init_completion(&irq_event); - - status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH", - &irq_event); - if (status < 0) { - dev_err(dev, "could not claim irq %d: %d\n", irq_num, status); - goto fail_irq; - } - - task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); - if (IS_ERR(task)) { - dev_err(dev, "could not create irq %d thread!\n", irq_num); - status = PTR_ERR(task); - goto fail_kthread; - } - - twl_irq = irq_num; - register_pm_notifier(&twl6030_irq_pm_notifier_block); - return irq_base; - -fail_kthread: - free_irq(irq_num, &irq_event); - -fail_irq: - for (i = irq_base; i < irq_end; i++) - irq_set_chip_and_handler(i, NULL, NULL); - - return status; -} - -int twl6030_exit_irq(void) -{ - unregister_pm_notifier(&twl6030_irq_pm_notifier_block); - - if (twl6030_irq_base) { - pr_err("twl6030: can't yet clean up IRQs?\n"); - return -ENOSYS; - } - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/mfd/twl6030-pwm.c b/ANDROID_3.4.5/drivers/mfd/twl6030-pwm.c deleted file mode 100644 index e8fee147..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl6030-pwm.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * twl6030_pwm.c - * Driver for PHOENIX (TWL6030) Pulse Width Modulator - * - * Copyright (C) 2010 Texas Instruments - * Author: Hemanth V <hemanthv@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed 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, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/i2c/twl.h> -#include <linux/slab.h> - -#define LED_PWM_CTRL1 0xF4 -#define LED_PWM_CTRL2 0xF5 - -/* Max value for CTRL1 register */ -#define PWM_CTRL1_MAX 255 - -/* Pull down disable */ -#define PWM_CTRL2_DIS_PD (1 << 6) - -/* Current control 2.5 milli Amps */ -#define PWM_CTRL2_CURR_02 (2 << 4) - -/* LED supply source */ -#define PWM_CTRL2_SRC_VAC (1 << 2) - -/* LED modes */ -#define PWM_CTRL2_MODE_HW (0 << 0) -#define PWM_CTRL2_MODE_SW (1 << 0) -#define PWM_CTRL2_MODE_DIS (2 << 0) - -#define PWM_CTRL2_MODE_MASK 0x3 - -struct pwm_device { - const char *label; - unsigned int pwm_id; -}; - -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - u8 duty_cycle; - int ret; - - if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) - return -EINVAL; - - duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1); - - if (ret < 0) { - pr_err("%s: Failed to configure PWM, Error %d\n", - pwm->label, ret); - return ret; - } - return 0; -} -EXPORT_SYMBOL(pwm_config); - -int pwm_enable(struct pwm_device *pwm) -{ - u8 val; - int ret; - - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); - if (ret < 0) { - pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret); - return ret; - } - - /* Change mode to software control */ - val &= ~PWM_CTRL2_MODE_MASK; - val |= PWM_CTRL2_MODE_SW; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); - if (ret < 0) { - pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret); - return ret; - } - - twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); - return 0; -} -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - u8 val; - int ret; - - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); - if (ret < 0) { - pr_err("%s: Failed to disable PWM, Error %d\n", - pwm->label, ret); - return; - } - - val &= ~PWM_CTRL2_MODE_MASK; - val |= PWM_CTRL2_MODE_HW; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); - if (ret < 0) { - pr_err("%s: Failed to disable PWM, Error %d\n", - pwm->label, ret); - return; - } - return; -} -EXPORT_SYMBOL(pwm_disable); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - u8 val; - int ret; - struct pwm_device *pwm; - - pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (pwm == NULL) { - pr_err("%s: failed to allocate memory\n", label); - return NULL; - } - - pwm->label = label; - pwm->pwm_id = pwm_id; - - /* Configure PWM */ - val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC | - PWM_CTRL2_MODE_HW; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); - - if (ret < 0) { - pr_err("%s: Failed to configure PWM, Error %d\n", - pwm->label, ret); - - kfree(pwm); - return NULL; - } - - return pwm; -} -EXPORT_SYMBOL(pwm_request); - -void pwm_free(struct pwm_device *pwm) -{ - pwm_disable(pwm); - kfree(pwm); -} -EXPORT_SYMBOL(pwm_free); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl6040-core.c b/ANDROID_3.4.5/drivers/mfd/twl6040-core.c deleted file mode 100644 index 2d6bedad..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl6040-core.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * MFD driver for TWL6040 audio device - * - * Authors: Misael Lopez Cruz <misael.lopez@ti.com> - * Jorge Eduardo Candelaria <jorge.candelaria@ti.com> - * Peter Ujfalusi <peter.ujfalusi@ti.com> - * - * Copyright: (C) 2011 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/delay.h> -#include <linux/i2c.h> -#include <linux/regmap.h> -#include <linux/err.h> -#include <linux/mfd/core.h> -#include <linux/mfd/twl6040.h> - -#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) - -int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) -{ - int ret; - unsigned int val; - - mutex_lock(&twl6040->io_mutex); - /* Vibra control registers from cache */ - if (unlikely(reg == TWL6040_REG_VIBCTLL || - reg == TWL6040_REG_VIBCTLR)) { - val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; - } else { - ret = regmap_read(twl6040->regmap, reg, &val); - if (ret < 0) { - mutex_unlock(&twl6040->io_mutex); - return ret; - } - } - mutex_unlock(&twl6040->io_mutex); - - return val; -} -EXPORT_SYMBOL(twl6040_reg_read); - -int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) -{ - int ret; - - mutex_lock(&twl6040->io_mutex); - ret = regmap_write(twl6040->regmap, reg, val); - /* Cache the vibra control registers */ - if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) - twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; - mutex_unlock(&twl6040->io_mutex); - - return ret; -} -EXPORT_SYMBOL(twl6040_reg_write); - -int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) -{ - int ret; - - mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, mask); - mutex_unlock(&twl6040->io_mutex); - return ret; -} -EXPORT_SYMBOL(twl6040_set_bits); - -int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) -{ - int ret; - - mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, 0); - mutex_unlock(&twl6040->io_mutex); - return ret; -} -EXPORT_SYMBOL(twl6040_clear_bits); - -/* twl6040 codec manual power-up sequence */ -static int twl6040_power_up(struct twl6040 *twl6040) -{ - u8 ldoctl, ncpctl, lppllctl; - int ret; - - /* enable high-side LDO, reference system and internal oscillator */ - ldoctl = TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA; - ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - if (ret) - return ret; - usleep_range(10000, 10500); - - /* enable negative charge pump */ - ncpctl = TWL6040_NCPENA; - ret = twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl); - if (ret) - goto ncp_err; - usleep_range(1000, 1500); - - /* enable low-side LDO */ - ldoctl |= TWL6040_LSLDOENA; - ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - if (ret) - goto lsldo_err; - usleep_range(1000, 1500); - - /* enable low-power PLL */ - lppllctl = TWL6040_LPLLENA; - ret = twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); - if (ret) - goto lppll_err; - usleep_range(5000, 5500); - - /* disable internal oscillator */ - ldoctl &= ~TWL6040_OSCENA; - ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - if (ret) - goto osc_err; - - return 0; - -osc_err: - lppllctl &= ~TWL6040_LPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); -lppll_err: - ldoctl &= ~TWL6040_LSLDOENA; - twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); -lsldo_err: - ncpctl &= ~TWL6040_NCPENA; - twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl); -ncp_err: - ldoctl &= ~(TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA); - twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - - return ret; -} - -/* twl6040 manual power-down sequence */ -static void twl6040_power_down(struct twl6040 *twl6040) -{ - u8 ncpctl, ldoctl, lppllctl; - - ncpctl = twl6040_reg_read(twl6040, TWL6040_REG_NCPCTL); - ldoctl = twl6040_reg_read(twl6040, TWL6040_REG_LDOCTL); - lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL); - - /* enable internal oscillator */ - ldoctl |= TWL6040_OSCENA; - twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - usleep_range(1000, 1500); - - /* disable low-power PLL */ - lppllctl &= ~TWL6040_LPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); - - /* disable low-side LDO */ - ldoctl &= ~TWL6040_LSLDOENA; - twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); - - /* disable negative charge pump */ - ncpctl &= ~TWL6040_NCPENA; - twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl); - - /* disable high-side LDO, reference system and internal oscillator */ - ldoctl &= ~(TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA); - twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl); -} - -static irqreturn_t twl6040_naudint_handler(int irq, void *data) -{ - struct twl6040 *twl6040 = data; - u8 intid, status; - - intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); - - if (intid & TWL6040_READYINT) - complete(&twl6040->ready); - - if (intid & TWL6040_THINT) { - status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); - if (status & TWL6040_TSHUTDET) { - dev_warn(twl6040->dev, - "Thermal shutdown, powering-off"); - twl6040_power(twl6040, 0); - } else { - dev_warn(twl6040->dev, - "Leaving thermal shutdown, powering-on"); - twl6040_power(twl6040, 1); - } - } - - return IRQ_HANDLED; -} - -static int twl6040_power_up_completion(struct twl6040 *twl6040, - int naudint) -{ - int time_left; - u8 intid; - - time_left = wait_for_completion_timeout(&twl6040->ready, - msecs_to_jiffies(144)); - if (!time_left) { - intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); - if (!(intid & TWL6040_READYINT)) { - dev_err(twl6040->dev, - "timeout waiting for READYINT\n"); - return -ETIMEDOUT; - } - } - - return 0; -} - -int twl6040_power(struct twl6040 *twl6040, int on) -{ - int audpwron = twl6040->audpwron; - int naudint = twl6040->irq; - int ret = 0; - - mutex_lock(&twl6040->mutex); - - if (on) { - /* already powered-up */ - if (twl6040->power_count++) - goto out; - - if (gpio_is_valid(audpwron)) { - /* use AUDPWRON line */ - gpio_set_value(audpwron, 1); - /* wait for power-up completion */ - ret = twl6040_power_up_completion(twl6040, naudint); - if (ret) { - dev_err(twl6040->dev, - "automatic power-down failed\n"); - twl6040->power_count = 0; - goto out; - } - } else { - /* use manual power-up sequence */ - ret = twl6040_power_up(twl6040); - if (ret) { - dev_err(twl6040->dev, - "manual power-up failed\n"); - twl6040->power_count = 0; - goto out; - } - } - /* Default PLL configuration after power up */ - twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; - twl6040->sysclk = 19200000; - twl6040->mclk = 32768; - } else { - /* already powered-down */ - if (!twl6040->power_count) { - dev_err(twl6040->dev, - "device is already powered-off\n"); - ret = -EPERM; - goto out; - } - - if (--twl6040->power_count) - goto out; - - if (gpio_is_valid(audpwron)) { - /* use AUDPWRON line */ - gpio_set_value(audpwron, 0); - - /* power-down sequence latency */ - usleep_range(500, 700); - } else { - /* use manual power-down sequence */ - twl6040_power_down(twl6040); - } - twl6040->sysclk = 0; - twl6040->mclk = 0; - } - -out: - mutex_unlock(&twl6040->mutex); - return ret; -} -EXPORT_SYMBOL(twl6040_power); - -int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, - unsigned int freq_in, unsigned int freq_out) -{ - u8 hppllctl, lppllctl; - int ret = 0; - - mutex_lock(&twl6040->mutex); - - hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL); - lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL); - - /* Force full reconfiguration when switching between PLL */ - if (pll_id != twl6040->pll) { - twl6040->sysclk = 0; - twl6040->mclk = 0; - } - - switch (pll_id) { - case TWL6040_SYSCLK_SEL_LPPLL: - /* low-power PLL divider */ - /* Change the sysclk configuration only if it has been canged */ - if (twl6040->sysclk != freq_out) { - switch (freq_out) { - case 17640000: - lppllctl |= TWL6040_LPLLFIN; - break; - case 19200000: - lppllctl &= ~TWL6040_LPLLFIN; - break; - default: - dev_err(twl6040->dev, - "freq_out %d not supported\n", - freq_out); - ret = -EINVAL; - goto pll_out; - } - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - } - - /* The PLL in use has not been change, we can exit */ - if (twl6040->pll == pll_id) - break; - - switch (freq_in) { - case 32768: - lppllctl |= TWL6040_LPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - mdelay(5); - lppllctl &= ~TWL6040_HPLLSEL; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - hppllctl &= ~TWL6040_HPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, - hppllctl); - break; - default: - dev_err(twl6040->dev, - "freq_in %d not supported\n", freq_in); - ret = -EINVAL; - goto pll_out; - } - break; - case TWL6040_SYSCLK_SEL_HPPLL: - /* high-performance PLL can provide only 19.2 MHz */ - if (freq_out != 19200000) { - dev_err(twl6040->dev, - "freq_out %d not supported\n", freq_out); - ret = -EINVAL; - goto pll_out; - } - - if (twl6040->mclk != freq_in) { - hppllctl &= ~TWL6040_MCLK_MSK; - - switch (freq_in) { - case 12000000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_12000KHZ | - TWL6040_HPLLENA; - break; - case 19200000: - /* - * PLL disabled - * (enable PLL if MCLK jitter quality - * doesn't meet specification) - */ - hppllctl |= TWL6040_MCLK_19200KHZ; - break; - case 26000000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_26000KHZ | - TWL6040_HPLLENA; - break; - case 38400000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_38400KHZ | - TWL6040_HPLLENA; - break; - default: - dev_err(twl6040->dev, - "freq_in %d not supported\n", freq_in); - ret = -EINVAL; - goto pll_out; - } - - /* - * enable clock slicer to ensure input waveform is - * square - */ - hppllctl |= TWL6040_HPLLSQRENA; - - twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, - hppllctl); - usleep_range(500, 700); - lppllctl |= TWL6040_HPLLSEL; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - lppllctl &= ~TWL6040_LPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - } - break; - default: - dev_err(twl6040->dev, "unknown pll id %d\n", pll_id); - ret = -EINVAL; - goto pll_out; - } - - twl6040->sysclk = freq_out; - twl6040->mclk = freq_in; - twl6040->pll = pll_id; - -pll_out: - mutex_unlock(&twl6040->mutex); - return ret; -} -EXPORT_SYMBOL(twl6040_set_pll); - -int twl6040_get_pll(struct twl6040 *twl6040) -{ - if (twl6040->power_count) - return twl6040->pll; - else - return -ENODEV; -} -EXPORT_SYMBOL(twl6040_get_pll); - -unsigned int twl6040_get_sysclk(struct twl6040 *twl6040) -{ - return twl6040->sysclk; -} -EXPORT_SYMBOL(twl6040_get_sysclk); - -/* Get the combined status of the vibra control register */ -int twl6040_get_vibralr_status(struct twl6040 *twl6040) -{ - u8 status; - - status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1]; - status &= (TWL6040_VIBENA | TWL6040_VIBSEL); - - return status; -} -EXPORT_SYMBOL(twl6040_get_vibralr_status); - -static struct resource twl6040_vibra_rsrc[] = { - { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource twl6040_codec_rsrc[] = { - { - .flags = IORESOURCE_IRQ, - }, -}; - -static bool twl6040_readable_reg(struct device *dev, unsigned int reg) -{ - /* Register 0 is not readable */ - if (!reg) - return false; - return true; -} - -static struct regmap_config twl6040_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = TWL6040_REG_STATUS, /* 0x2e */ - - .readable_reg = twl6040_readable_reg, -}; - -static int __devinit twl6040_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct twl6040_platform_data *pdata = client->dev.platform_data; - struct twl6040 *twl6040; - struct mfd_cell *cell = NULL; - int ret, children = 0; - - if (!pdata) { - dev_err(&client->dev, "Platform data is missing\n"); - return -EINVAL; - } - - /* In order to operate correctly we need valid interrupt config */ - if (!client->irq || !pdata->irq_base) { - dev_err(&client->dev, "Invalid IRQ configuration\n"); - return -EINVAL; - } - - twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), - GFP_KERNEL); - if (!twl6040) { - ret = -ENOMEM; - goto err; - } - - twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); - if (IS_ERR(twl6040->regmap)) { - ret = PTR_ERR(twl6040->regmap); - goto err; - } - - i2c_set_clientdata(client, twl6040); - - twl6040->dev = &client->dev; - twl6040->irq = client->irq; - twl6040->irq_base = pdata->irq_base; - - mutex_init(&twl6040->mutex); - mutex_init(&twl6040->io_mutex); - init_completion(&twl6040->ready); - - twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); - - /* ERRATA: Automatic power-up is not possible in ES1.0 */ - if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) - twl6040->audpwron = pdata->audpwron_gpio; - else - twl6040->audpwron = -EINVAL; - - if (gpio_is_valid(twl6040->audpwron)) { - ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW, - "audpwron"); - if (ret) - goto gpio1_err; - } - - /* codec interrupt */ - ret = twl6040_irq_init(twl6040); - if (ret) - goto gpio2_err; - - ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY, - NULL, twl6040_naudint_handler, 0, - "twl6040_irq_ready", twl6040); - if (ret) { - dev_err(twl6040->dev, "READY IRQ request failed: %d\n", - ret); - goto irq_err; - } - - /* dual-access registers controlled by I2C only */ - twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); - - if (pdata->codec) { - int irq = twl6040->irq_base + TWL6040_IRQ_PLUG; - - cell = &twl6040->cells[children]; - cell->name = "twl6040-codec"; - twl6040_codec_rsrc[0].start = irq; - twl6040_codec_rsrc[0].end = irq; - cell->resources = twl6040_codec_rsrc; - cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); - cell->platform_data = pdata->codec; - cell->pdata_size = sizeof(*pdata->codec); - children++; - } - - if (pdata->vibra) { - int irq = twl6040->irq_base + TWL6040_IRQ_VIB; - - cell = &twl6040->cells[children]; - cell->name = "twl6040-vibra"; - twl6040_vibra_rsrc[0].start = irq; - twl6040_vibra_rsrc[0].end = irq; - cell->resources = twl6040_vibra_rsrc; - cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); - - cell->platform_data = pdata->vibra; - cell->pdata_size = sizeof(*pdata->vibra); - children++; - } - - if (children) { - ret = mfd_add_devices(&client->dev, -1, twl6040->cells, - children, NULL, 0); - if (ret) - goto mfd_err; - } else { - dev_err(&client->dev, "No platform data found for children\n"); - ret = -ENODEV; - goto mfd_err; - } - - return 0; - -mfd_err: - free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); -irq_err: - twl6040_irq_exit(twl6040); -gpio2_err: - if (gpio_is_valid(twl6040->audpwron)) - gpio_free(twl6040->audpwron); -gpio1_err: - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); -err: - return ret; -} - -static int __devexit twl6040_remove(struct i2c_client *client) -{ - struct twl6040 *twl6040 = i2c_get_clientdata(client); - - if (twl6040->power_count) - twl6040_power(twl6040, 0); - - if (gpio_is_valid(twl6040->audpwron)) - gpio_free(twl6040->audpwron); - - free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); - twl6040_irq_exit(twl6040); - - mfd_remove_devices(&client->dev); - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); - - return 0; -} - -static const struct i2c_device_id twl6040_i2c_id[] = { - { "twl6040", 0, }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); - -static struct i2c_driver twl6040_driver = { - .driver = { - .name = "twl6040", - .owner = THIS_MODULE, - }, - .probe = twl6040_probe, - .remove = __devexit_p(twl6040_remove), - .id_table = twl6040_i2c_id, -}; - -module_i2c_driver(twl6040_driver); - -MODULE_DESCRIPTION("TWL6040 MFD"); -MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); -MODULE_AUTHOR("Jorge Eduardo Candelaria <jorge.candelaria@ti.com>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:twl6040"); diff --git a/ANDROID_3.4.5/drivers/mfd/twl6040-irq.c b/ANDROID_3.4.5/drivers/mfd/twl6040-irq.c deleted file mode 100644 index b3f8ddaa..00000000 --- a/ANDROID_3.4.5/drivers/mfd/twl6040-irq.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Interrupt controller support for TWL6040 - * - * Author: Misael Lopez Cruz <misael.lopez@ti.com> - * - * Copyright: (C) 2011 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/mfd/core.h> -#include <linux/mfd/twl6040.h> - -struct twl6040_irq_data { - int mask; - int status; -}; - -static struct twl6040_irq_data twl6040_irqs[] = { - { - .mask = TWL6040_THMSK, - .status = TWL6040_THINT, - }, - { - .mask = TWL6040_PLUGMSK, - .status = TWL6040_PLUGINT | TWL6040_UNPLUGINT, - }, - { - .mask = TWL6040_HOOKMSK, - .status = TWL6040_HOOKINT, - }, - { - .mask = TWL6040_HFMSK, - .status = TWL6040_HFINT, - }, - { - .mask = TWL6040_VIBMSK, - .status = TWL6040_VIBINT, - }, - { - .mask = TWL6040_READYMSK, - .status = TWL6040_READYINT, - }, -}; - -static inline -struct twl6040_irq_data *irq_to_twl6040_irq(struct twl6040 *twl6040, - int irq) -{ - return &twl6040_irqs[irq - twl6040->irq_base]; -} - -static void twl6040_irq_lock(struct irq_data *data) -{ - struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data); - - mutex_lock(&twl6040->irq_mutex); -} - -static void twl6040_irq_sync_unlock(struct irq_data *data) -{ - struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data); - - /* write back to hardware any change in irq mask */ - if (twl6040->irq_masks_cur != twl6040->irq_masks_cache) { - twl6040->irq_masks_cache = twl6040->irq_masks_cur; - twl6040_reg_write(twl6040, TWL6040_REG_INTMR, - twl6040->irq_masks_cur); - } - - mutex_unlock(&twl6040->irq_mutex); -} - -static void twl6040_irq_enable(struct irq_data *data) -{ - struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data); - struct twl6040_irq_data *irq_data = irq_to_twl6040_irq(twl6040, - data->irq); - - twl6040->irq_masks_cur &= ~irq_data->mask; -} - -static void twl6040_irq_disable(struct irq_data *data) -{ - struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data); - struct twl6040_irq_data *irq_data = irq_to_twl6040_irq(twl6040, - data->irq); - - twl6040->irq_masks_cur |= irq_data->mask; -} - -static struct irq_chip twl6040_irq_chip = { - .name = "twl6040", - .irq_bus_lock = twl6040_irq_lock, - .irq_bus_sync_unlock = twl6040_irq_sync_unlock, - .irq_enable = twl6040_irq_enable, - .irq_disable = twl6040_irq_disable, -}; - -static irqreturn_t twl6040_irq_thread(int irq, void *data) -{ - struct twl6040 *twl6040 = data; - u8 intid; - int i; - - intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); - - /* apply masking and report (backwards to handle READYINT first) */ - for (i = ARRAY_SIZE(twl6040_irqs) - 1; i >= 0; i--) { - if (twl6040->irq_masks_cur & twl6040_irqs[i].mask) - intid &= ~twl6040_irqs[i].status; - if (intid & twl6040_irqs[i].status) - handle_nested_irq(twl6040->irq_base + i); - } - - /* ack unmasked irqs */ - twl6040_reg_write(twl6040, TWL6040_REG_INTID, intid); - - return IRQ_HANDLED; -} - -int twl6040_irq_init(struct twl6040 *twl6040) -{ - int cur_irq, ret; - u8 val; - - mutex_init(&twl6040->irq_mutex); - - /* mask the individual interrupt sources */ - twl6040->irq_masks_cur = TWL6040_ALLINT_MSK; - twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; - twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); - - /* Register them with genirq */ - for (cur_irq = twl6040->irq_base; - cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs); - cur_irq++) { - irq_set_chip_data(cur_irq, twl6040); - irq_set_chip_and_handler(cur_irq, &twl6040_irq_chip, - handle_level_irq); - irq_set_nested_thread(cur_irq, 1); - - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(twl6040->irq, NULL, twl6040_irq_thread, - IRQF_ONESHOT, "twl6040", twl6040); - if (ret) { - dev_err(twl6040->dev, "failed to request IRQ %d: %d\n", - twl6040->irq, ret); - return ret; - } - - /* reset interrupts */ - val = twl6040_reg_read(twl6040, TWL6040_REG_INTID); - - /* interrupts cleared on write */ - twl6040_clear_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_INTCLRMODE); - - return 0; -} -EXPORT_SYMBOL(twl6040_irq_init); - -void twl6040_irq_exit(struct twl6040 *twl6040) -{ - free_irq(twl6040->irq, twl6040); -} -EXPORT_SYMBOL(twl6040_irq_exit); diff --git a/ANDROID_3.4.5/drivers/mfd/ucb1400_core.c b/ANDROID_3.4.5/drivers/mfd/ucb1400_core.c deleted file mode 100644 index daf69527..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ucb1400_core.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Core functions for: - * Philips UCB1400 multifunction chip - * - * Based on ucb1400_ts.c: - * Author: Nicolas Pitre - * Created: September 25, 2006 - * Copyright: MontaVista Software, Inc. - * - * Spliting done by: Marek Vasut <marek.vasut@gmail.com> - * If something doesn't work and it worked before spliting, e-mail me, - * dont bother Nicolas please ;-) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This code is heavily based on ucb1x00-*.c copyrighted by Russell King - * covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has - * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request. - */ - -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/ucb1400.h> - -unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, - int adcsync) -{ - unsigned int val; - - if (adcsync) - adc_channel |= UCB_ADC_SYNC_ENA; - - ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); - ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | - UCB_ADC_START); - - while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA)) - & UCB_ADC_DAT_VALID)) - schedule_timeout_uninterruptible(1); - - return val & UCB_ADC_DAT_MASK; -} -EXPORT_SYMBOL_GPL(ucb1400_adc_read); - -static int ucb1400_core_probe(struct device *dev) -{ - int err; - struct ucb1400 *ucb; - struct ucb1400_ts ucb_ts; - struct ucb1400_gpio ucb_gpio; - struct snd_ac97 *ac97; - struct ucb1400_pdata *pdata = dev->platform_data; - - memset(&ucb_ts, 0, sizeof(ucb_ts)); - memset(&ucb_gpio, 0, sizeof(ucb_gpio)); - - ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL); - if (!ucb) { - err = -ENOMEM; - goto err; - } - - dev_set_drvdata(dev, ucb); - - ac97 = to_ac97_t(dev); - - ucb_ts.id = ucb1400_reg_read(ac97, UCB_ID); - if (ucb_ts.id != UCB_ID_1400) { - err = -ENODEV; - goto err0; - } - - /* GPIO */ - ucb_gpio.ac97 = ac97; - ucb->ucb1400_gpio = platform_device_alloc("ucb1400_gpio", -1); - if (!ucb->ucb1400_gpio) { - err = -ENOMEM; - goto err0; - } - err = platform_device_add_data(ucb->ucb1400_gpio, &ucb_gpio, - sizeof(ucb_gpio)); - if (err) - goto err1; - err = platform_device_add(ucb->ucb1400_gpio); - if (err) - goto err1; - - /* TOUCHSCREEN */ - ucb_ts.ac97 = ac97; - - if (pdata != NULL && pdata->irq >= 0) - ucb_ts.irq = pdata->irq; - else - ucb_ts.irq = -1; - - ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1); - if (!ucb->ucb1400_ts) { - err = -ENOMEM; - goto err2; - } - err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts, - sizeof(ucb_ts)); - if (err) - goto err3; - err = platform_device_add(ucb->ucb1400_ts); - if (err) - goto err3; - - return 0; - -err3: - platform_device_put(ucb->ucb1400_ts); -err2: - platform_device_del(ucb->ucb1400_gpio); -err1: - platform_device_put(ucb->ucb1400_gpio); -err0: - kfree(ucb); -err: - return err; -} - -static int ucb1400_core_remove(struct device *dev) -{ - struct ucb1400 *ucb = dev_get_drvdata(dev); - - platform_device_unregister(ucb->ucb1400_ts); - platform_device_unregister(ucb->ucb1400_gpio); - - kfree(ucb); - return 0; -} - -static struct device_driver ucb1400_core_driver = { - .name = "ucb1400_core", - .bus = &ac97_bus_type, - .probe = ucb1400_core_probe, - .remove = ucb1400_core_remove, -}; - -static int __init ucb1400_core_init(void) -{ - return driver_register(&ucb1400_core_driver); -} - -static void __exit ucb1400_core_exit(void) -{ - driver_unregister(&ucb1400_core_driver); -} - -module_init(ucb1400_core_init); -module_exit(ucb1400_core_exit); - -MODULE_DESCRIPTION("Philips UCB1400 driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ucb1x00-assabet.c b/ANDROID_3.4.5/drivers/mfd/ucb1x00-assabet.c deleted file mode 100644 index b63c0756..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ucb1x00-assabet.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * linux/drivers/mfd/ucb1x00-assabet.c - * - * Copyright (C) 2001-2003 Russell King, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * We handle the machine-specific bits of the UCB1x00 driver here. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/err.h> -#include <linux/fs.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/proc_fs.h> -#include <linux/mfd/ucb1x00.h> - -#define UCB1X00_ATTR(name,input)\ -static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ - int val; \ - ucb1x00_adc_enable(ucb); \ - val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \ - ucb1x00_adc_disable(ucb); \ - return sprintf(buf, "%d\n", val); \ -} \ -static DEVICE_ATTR(name,0444,name##_show,NULL) - -UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); -UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); -UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); - -static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) -{ - struct ucb1x00 *ucb = dev->ucb; - struct platform_device *pdev; - struct gpio_keys_platform_data keys; - static struct gpio_keys_button buttons[6]; - unsigned i; - - memset(buttons, 0, sizeof(buttons)); - memset(&keys, 0, sizeof(keys)); - - for (i = 0; i < ARRAY_SIZE(buttons); i++) { - buttons[i].code = BTN_0 + i; - buttons[i].gpio = ucb->gpio.base + i; - buttons[i].type = EV_KEY; - buttons[i].can_disable = true; - } - - keys.buttons = buttons; - keys.nbuttons = ARRAY_SIZE(buttons); - keys.poll_interval = 50; - keys.name = "ucb1x00"; - - pdev = platform_device_register_data(&ucb->dev, "gpio-keys", -1, - &keys, sizeof(keys)); - - device_create_file(&ucb->dev, &dev_attr_vbatt); - device_create_file(&ucb->dev, &dev_attr_vcharger); - device_create_file(&ucb->dev, &dev_attr_batt_temp); - - dev->priv = pdev; - return 0; -} - -static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) -{ - struct platform_device *pdev = dev->priv; - - if (!IS_ERR(pdev)) - platform_device_unregister(pdev); - - device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); - device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); - device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); -} - -static struct ucb1x00_driver ucb1x00_assabet_driver = { - .add = ucb1x00_assabet_add, - .remove = ucb1x00_assabet_remove, -}; - -static int __init ucb1x00_assabet_init(void) -{ - return ucb1x00_register_driver(&ucb1x00_assabet_driver); -} - -static void __exit ucb1x00_assabet_exit(void) -{ - ucb1x00_unregister_driver(&ucb1x00_assabet_driver); -} - -module_init(ucb1x00_assabet_init); -module_exit(ucb1x00_assabet_exit); - -MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); -MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ucb1x00-core.c b/ANDROID_3.4.5/drivers/mfd/ucb1x00-core.c deleted file mode 100644 index 70f02dae..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ucb1x00-core.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * linux/drivers/mfd/ucb1x00-core.c - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * The UCB1x00 core driver provides basic services for handling IO, - * the ADC, interrupts, and accessing registers. It is designed - * such that everything goes through this layer, thereby providing - * a consistent locking methodology, as well as allowing the drivers - * to be used on other non-MCP-enabled hardware platforms. - * - * Note that all locks are private to this file. Nothing else may - * touch them. - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/device.h> -#include <linux/mutex.h> -#include <linux/mfd/ucb1x00.h> -#include <linux/pm.h> -#include <linux/gpio.h> - -static DEFINE_MUTEX(ucb1x00_mutex); -static LIST_HEAD(ucb1x00_drivers); -static LIST_HEAD(ucb1x00_devices); - -/** - * ucb1x00_io_set_dir - set IO direction - * @ucb: UCB1x00 structure describing chip - * @in: bitfield of IO pins to be set as inputs - * @out: bitfield of IO pins to be set as outputs - * - * Set the IO direction of the ten general purpose IO pins on - * the UCB1x00 chip. The @in bitfield has priority over the - * @out bitfield, in that if you specify a pin as both input - * and output, it will end up as an input. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function takes a spinlock, disabling interrupts. - */ -void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out) -{ - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_dir |= out; - ucb->io_dir &= ~in; - - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - spin_unlock_irqrestore(&ucb->io_lock, flags); -} - -/** - * ucb1x00_io_write - set or clear IO outputs - * @ucb: UCB1x00 structure describing chip - * @set: bitfield of IO pins to set to logic '1' - * @clear: bitfield of IO pins to set to logic '0' - * - * Set the IO output state of the specified IO pins. The value - * is retained if the pins are subsequently configured as inputs. - * The @clear bitfield has priority over the @set bitfield - - * outputs will be cleared. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function takes a spinlock, disabling interrupts. - */ -void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear) -{ - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_out |= set; - ucb->io_out &= ~clear; - - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - spin_unlock_irqrestore(&ucb->io_lock, flags); -} - -/** - * ucb1x00_io_read - read the current state of the IO pins - * @ucb: UCB1x00 structure describing chip - * - * Return a bitfield describing the logic state of the ten - * general purpose IO pins. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function does not take any mutexes or spinlocks. - */ -unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) -{ - return ucb1x00_reg_read(ucb, UCB_IO_DATA); -} - -static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - if (value) - ucb->io_out |= 1 << offset; - else - ucb->io_out &= ~(1 << offset); - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); -} - -static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); - unsigned val; - - ucb1x00_enable(ucb); - val = ucb1x00_reg_read(ucb, UCB_IO_DATA); - ucb1x00_disable(ucb); - - return val & (1 << offset); -} - -static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_dir &= ~(1 << offset); - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); - - return 0; -} - -static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset - , int value) -{ - struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); - unsigned long flags; - unsigned old, mask = 1 << offset; - - spin_lock_irqsave(&ucb->io_lock, flags); - old = ucb->io_out; - if (value) - ucb->io_out |= mask; - else - ucb->io_out &= ~mask; - - ucb1x00_enable(ucb); - if (old != ucb->io_out) - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - - if (!(ucb->io_dir & mask)) { - ucb->io_dir |= mask; - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - } - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); - - return 0; -} - -static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); - - return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO; -} - -/* - * UCB1300 data sheet says we must: - * 1. enable ADC => 5us (including reference startup time) - * 2. select input => 51*tsibclk => 4.3us - * 3. start conversion => 102*tsibclk => 8.5us - * (tsibclk = 1/11981000) - * Period between SIB 128-bit frames = 10.7us - */ - -/** - * ucb1x00_adc_enable - enable the ADC converter - * @ucb: UCB1x00 structure describing chip - * - * Enable the ucb1x00 and ADC converter on the UCB1x00 for use. - * Any code wishing to use the ADC converter must call this - * function prior to using it. - * - * This function takes the ADC mutex to prevent two or more - * concurrent uses, and therefore may sleep. As a result, it - * can only be called from process context, not interrupt - * context. - * - * You should release the ADC as soon as possible using - * ucb1x00_adc_disable. - */ -void ucb1x00_adc_enable(struct ucb1x00 *ucb) -{ - mutex_lock(&ucb->adc_mutex); - - ucb->adc_cr |= UCB_ADC_ENA; - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); -} - -/** - * ucb1x00_adc_read - read the specified ADC channel - * @ucb: UCB1x00 structure describing chip - * @adc_channel: ADC channel mask - * @sync: wait for syncronisation pulse. - * - * Start an ADC conversion and wait for the result. Note that - * synchronised ADC conversions (via the ADCSYNC pin) must wait - * until the trigger is asserted and the conversion is finished. - * - * This function currently spins waiting for the conversion to - * complete (2 frames max without sync). - * - * If called for a synchronised ADC conversion, it may sleep - * with the ADC mutex held. - */ -unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync) -{ - unsigned int val; - - if (sync) - adc_channel |= UCB_ADC_SYNC_ENA; - - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel); - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START); - - for (;;) { - val = ucb1x00_reg_read(ucb, UCB_ADC_DATA); - if (val & UCB_ADC_DAT_VAL) - break; - /* yield to other processes */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - return UCB_ADC_DAT(val); -} - -/** - * ucb1x00_adc_disable - disable the ADC converter - * @ucb: UCB1x00 structure describing chip - * - * Disable the ADC converter and release the ADC mutex. - */ -void ucb1x00_adc_disable(struct ucb1x00 *ucb) -{ - ucb->adc_cr &= ~UCB_ADC_ENA; - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); - ucb1x00_disable(ucb); - - mutex_unlock(&ucb->adc_mutex); -} - -/* - * UCB1x00 Interrupt handling. - * - * The UCB1x00 can generate interrupts when the SIBCLK is stopped. - * Since we need to read an internal register, we must re-enable - * SIBCLK to talk to the chip. We leave the clock running until - * we have finished processing all interrupts from the chip. - */ -static void ucb1x00_irq(unsigned int irq, struct irq_desc *desc) -{ - struct ucb1x00 *ucb = irq_desc_get_handler_data(desc); - unsigned int isr, i; - - ucb1x00_enable(ucb); - isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - for (i = 0; i < 16 && isr; i++, isr >>= 1, irq++) - if (isr & 1) - generic_handle_irq(ucb->irq_base + i); - ucb1x00_disable(ucb); -} - -static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask) -{ - ucb1x00_enable(ucb); - if (ucb->irq_ris_enbl & mask) - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - if (ucb->irq_fal_enbl & mask) - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - ucb1x00_disable(ucb); -} - -static void ucb1x00_irq_noop(struct irq_data *data) -{ -} - -static void ucb1x00_irq_mask(struct irq_data *data) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - ucb->irq_mask &= ~mask; - ucb1x00_irq_update(ucb, mask); - raw_spin_unlock(&ucb->irq_lock); -} - -static void ucb1x00_irq_unmask(struct irq_data *data) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - ucb->irq_mask |= mask; - ucb1x00_irq_update(ucb, mask); - raw_spin_unlock(&ucb->irq_lock); -} - -static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - if (type & IRQ_TYPE_EDGE_RISING) - ucb->irq_ris_enbl |= mask; - else - ucb->irq_ris_enbl &= ~mask; - - if (type & IRQ_TYPE_EDGE_FALLING) - ucb->irq_fal_enbl |= mask; - else - ucb->irq_fal_enbl &= ~mask; - if (ucb->irq_mask & mask) { - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - } - raw_spin_unlock(&ucb->irq_lock); - - return 0; -} - -static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data; - unsigned mask = 1 << (data->irq - ucb->irq_base); - - if (!pdata || !pdata->can_wakeup) - return -EINVAL; - - raw_spin_lock(&ucb->irq_lock); - if (on) - ucb->irq_wake |= mask; - else - ucb->irq_wake &= ~mask; - raw_spin_unlock(&ucb->irq_lock); - - return 0; -} - -static struct irq_chip ucb1x00_irqchip = { - .name = "ucb1x00", - .irq_ack = ucb1x00_irq_noop, - .irq_mask = ucb1x00_irq_mask, - .irq_unmask = ucb1x00_irq_unmask, - .irq_set_type = ucb1x00_irq_set_type, - .irq_set_wake = ucb1x00_irq_set_wake, -}; - -static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv) -{ - struct ucb1x00_dev *dev; - int ret = -ENOMEM; - - dev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL); - if (dev) { - dev->ucb = ucb; - dev->drv = drv; - - ret = drv->add(dev); - - if (ret == 0) { - list_add_tail(&dev->dev_node, &ucb->devs); - list_add_tail(&dev->drv_node, &drv->devs); - } else { - kfree(dev); - } - } - return ret; -} - -static void ucb1x00_remove_dev(struct ucb1x00_dev *dev) -{ - dev->drv->remove(dev); - list_del(&dev->dev_node); - list_del(&dev->drv_node); - kfree(dev); -} - -/* - * Try to probe our interrupt, rather than relying on lots of - * hard-coded machine dependencies. For reference, the expected - * IRQ mappings are: - * - * Machine Default IRQ - * adsbitsy IRQ_GPCIN4 - * cerf IRQ_GPIO_UCB1200_IRQ - * flexanet IRQ_GPIO_GUI - * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ - * graphicsclient ADS_EXT_IRQ(8) - * graphicsmaster ADS_EXT_IRQ(8) - * lart LART_IRQ_UCB1200 - * omnimeter IRQ_GPIO23 - * pfs168 IRQ_GPIO_UCB1300_IRQ - * simpad IRQ_GPIO_UCB1300_IRQ - * shannon SHANNON_IRQ_GPIO_IRQ_CODEC - * yopy IRQ_GPIO_UCB1200_IRQ - */ -static int ucb1x00_detect_irq(struct ucb1x00 *ucb) -{ - unsigned long mask; - - mask = probe_irq_on(); - if (!mask) { - probe_irq_off(mask); - return NO_IRQ; - } - - /* - * Enable the ADC interrupt. - */ - ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); - ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* - * Cause an ADC interrupt. - */ - ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); - ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START); - - /* - * Wait for the conversion to complete. - */ - while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0); - ucb1x00_reg_write(ucb, UCB_ADC_CR, 0); - - /* - * Disable and clear interrupt. - */ - ucb1x00_reg_write(ucb, UCB_IE_RIS, 0); - ucb1x00_reg_write(ucb, UCB_IE_FAL, 0); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* - * Read triggered interrupt. - */ - return probe_irq_off(mask); -} - -static void ucb1x00_release(struct device *dev) -{ - struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); - kfree(ucb); -} - -static struct class ucb1x00_class = { - .name = "ucb1x00", - .dev_release = ucb1x00_release, -}; - -static int ucb1x00_probe(struct mcp *mcp) -{ - struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; - struct ucb1x00_driver *drv; - struct ucb1x00 *ucb; - unsigned id, i, irq_base; - int ret = -ENODEV; - - /* Tell the platform to deassert the UCB1x00 reset */ - if (pdata && pdata->reset) - pdata->reset(UCB_RST_PROBE); - - mcp_enable(mcp); - id = mcp_reg_read(mcp, UCB_ID); - mcp_disable(mcp); - - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); - goto out; - } - - ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL); - ret = -ENOMEM; - if (!ucb) - goto out; - - device_initialize(&ucb->dev); - ucb->dev.class = &ucb1x00_class; - ucb->dev.parent = &mcp->attached_device; - dev_set_name(&ucb->dev, "ucb1x00"); - - raw_spin_lock_init(&ucb->irq_lock); - spin_lock_init(&ucb->io_lock); - mutex_init(&ucb->adc_mutex); - - ucb->id = id; - ucb->mcp = mcp; - - ret = device_add(&ucb->dev); - if (ret) - goto err_dev_add; - - ucb1x00_enable(ucb); - ucb->irq = ucb1x00_detect_irq(ucb); - ucb1x00_disable(ucb); - if (ucb->irq == NO_IRQ) { - dev_err(&ucb->dev, "IRQ probe failed\n"); - ret = -ENODEV; - goto err_no_irq; - } - - ucb->gpio.base = -1; - irq_base = pdata ? pdata->irq_base : 0; - ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1); - if (ucb->irq_base < 0) { - dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n", - ucb->irq_base); - goto err_irq_alloc; - } - - for (i = 0; i < 16; i++) { - unsigned irq = ucb->irq_base + i; - - irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq); - irq_set_chip_data(irq, ucb); - set_irq_flags(irq, IRQF_VALID | IRQ_NOREQUEST); - } - - irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(ucb->irq, ucb); - irq_set_chained_handler(ucb->irq, ucb1x00_irq); - - if (pdata && pdata->gpio_base) { - ucb->gpio.label = dev_name(&ucb->dev); - ucb->gpio.dev = &ucb->dev; - ucb->gpio.owner = THIS_MODULE; - ucb->gpio.base = pdata->gpio_base; - ucb->gpio.ngpio = 10; - ucb->gpio.set = ucb1x00_gpio_set; - ucb->gpio.get = ucb1x00_gpio_get; - ucb->gpio.direction_input = ucb1x00_gpio_direction_input; - ucb->gpio.direction_output = ucb1x00_gpio_direction_output; - ucb->gpio.to_irq = ucb1x00_to_irq; - ret = gpiochip_add(&ucb->gpio); - if (ret) - goto err_gpio_add; - } else - dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); - - mcp_set_drvdata(mcp, ucb); - - if (pdata) - device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup); - - INIT_LIST_HEAD(&ucb->devs); - mutex_lock(&ucb1x00_mutex); - list_add_tail(&ucb->node, &ucb1x00_devices); - list_for_each_entry(drv, &ucb1x00_drivers, node) { - ucb1x00_add_dev(ucb, drv); - } - mutex_unlock(&ucb1x00_mutex); - - return ret; - - err_gpio_add: - irq_set_chained_handler(ucb->irq, NULL); - err_irq_alloc: - if (ucb->irq_base > 0) - irq_free_descs(ucb->irq_base, 16); - err_no_irq: - device_del(&ucb->dev); - err_dev_add: - put_device(&ucb->dev); - out: - if (pdata && pdata->reset) - pdata->reset(UCB_RST_PROBE_FAIL); - return ret; -} - -static void ucb1x00_remove(struct mcp *mcp) -{ - struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; - struct ucb1x00 *ucb = mcp_get_drvdata(mcp); - struct list_head *l, *n; - int ret; - - mutex_lock(&ucb1x00_mutex); - list_del(&ucb->node); - list_for_each_safe(l, n, &ucb->devs) { - struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node); - ucb1x00_remove_dev(dev); - } - mutex_unlock(&ucb1x00_mutex); - - if (ucb->gpio.base != -1) { - ret = gpiochip_remove(&ucb->gpio); - if (ret) - dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); - } - - irq_set_chained_handler(ucb->irq, NULL); - irq_free_descs(ucb->irq_base, 16); - device_unregister(&ucb->dev); - - if (pdata && pdata->reset) - pdata->reset(UCB_RST_REMOVE); -} - -int ucb1x00_register_driver(struct ucb1x00_driver *drv) -{ - struct ucb1x00 *ucb; - - INIT_LIST_HEAD(&drv->devs); - mutex_lock(&ucb1x00_mutex); - list_add_tail(&drv->node, &ucb1x00_drivers); - list_for_each_entry(ucb, &ucb1x00_devices, node) { - ucb1x00_add_dev(ucb, drv); - } - mutex_unlock(&ucb1x00_mutex); - return 0; -} - -void ucb1x00_unregister_driver(struct ucb1x00_driver *drv) -{ - struct list_head *n, *l; - - mutex_lock(&ucb1x00_mutex); - list_del(&drv->node); - list_for_each_safe(l, n, &drv->devs) { - struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node); - ucb1x00_remove_dev(dev); - } - mutex_unlock(&ucb1x00_mutex); -} - -static int ucb1x00_suspend(struct device *dev) -{ - struct ucb1x00_plat_data *pdata = dev->platform_data; - struct ucb1x00 *ucb = dev_get_drvdata(dev); - struct ucb1x00_dev *udev; - - mutex_lock(&ucb1x00_mutex); - list_for_each_entry(udev, &ucb->devs, dev_node) { - if (udev->drv->suspend) - udev->drv->suspend(udev); - } - mutex_unlock(&ucb1x00_mutex); - - if (ucb->irq_wake) { - unsigned long flags; - - raw_spin_lock_irqsave(&ucb->irq_lock, flags); - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_wake); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_wake); - ucb1x00_disable(ucb); - raw_spin_unlock_irqrestore(&ucb->irq_lock, flags); - - enable_irq_wake(ucb->irq); - } else if (pdata && pdata->reset) - pdata->reset(UCB_RST_SUSPEND); - - return 0; -} - -static int ucb1x00_resume(struct device *dev) -{ - struct ucb1x00_plat_data *pdata = dev->platform_data; - struct ucb1x00 *ucb = dev_get_drvdata(dev); - struct ucb1x00_dev *udev; - - if (!ucb->irq_wake && pdata && pdata->reset) - pdata->reset(UCB_RST_RESUME); - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - - if (ucb->irq_wake) { - unsigned long flags; - - raw_spin_lock_irqsave(&ucb->irq_lock, flags); - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - raw_spin_unlock_irqrestore(&ucb->irq_lock, flags); - - disable_irq_wake(ucb->irq); - } - ucb1x00_disable(ucb); - - mutex_lock(&ucb1x00_mutex); - list_for_each_entry(udev, &ucb->devs, dev_node) { - if (udev->drv->resume) - udev->drv->resume(udev); - } - mutex_unlock(&ucb1x00_mutex); - return 0; -} - -static const struct dev_pm_ops ucb1x00_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume) -}; - -static struct mcp_driver ucb1x00_driver = { - .drv = { - .name = "ucb1x00", - .owner = THIS_MODULE, - .pm = &ucb1x00_pm_ops, - }, - .probe = ucb1x00_probe, - .remove = ucb1x00_remove, -}; - -static int __init ucb1x00_init(void) -{ - int ret = class_register(&ucb1x00_class); - if (ret == 0) { - ret = mcp_driver_register(&ucb1x00_driver); - if (ret) - class_unregister(&ucb1x00_class); - } - return ret; -} - -static void __exit ucb1x00_exit(void) -{ - mcp_driver_unregister(&ucb1x00_driver); - class_unregister(&ucb1x00_class); -} - -module_init(ucb1x00_init); -module_exit(ucb1x00_exit); - -EXPORT_SYMBOL(ucb1x00_io_set_dir); -EXPORT_SYMBOL(ucb1x00_io_write); -EXPORT_SYMBOL(ucb1x00_io_read); - -EXPORT_SYMBOL(ucb1x00_adc_enable); -EXPORT_SYMBOL(ucb1x00_adc_read); -EXPORT_SYMBOL(ucb1x00_adc_disable); - -EXPORT_SYMBOL(ucb1x00_register_driver); -EXPORT_SYMBOL(ucb1x00_unregister_driver); - -MODULE_ALIAS("mcp:ucb1x00"); -MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); -MODULE_DESCRIPTION("UCB1x00 core driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/ucb1x00-ts.c b/ANDROID_3.4.5/drivers/mfd/ucb1x00-ts.c deleted file mode 100644 index 1e0e20c0..00000000 --- a/ANDROID_3.4.5/drivers/mfd/ucb1x00-ts.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Touchscreen driver for UCB1x00-based touchscreens - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - * Copyright (C) 2005 Pavel Machek - * - * 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. - * - * 21-Jan-2002 <jco@ict.es> : - * - * Added support for synchronous A/D mode. This mode is useful to - * avoid noise induced in the touchpanel by the LCD, provided that - * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin. - * It is important to note that the signal connected to the ADCSYNC - * pin should provide pulses even when the LCD is blanked, otherwise - * a pen touch needed to unblank the LCD will never be read. - */ -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/completion.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/input.h> -#include <linux/device.h> -#include <linux/freezer.h> -#include <linux/slab.h> -#include <linux/kthread.h> -#include <linux/mfd/ucb1x00.h> - -#include <mach/collie.h> -#include <asm/mach-types.h> - - - -struct ucb1x00_ts { - struct input_dev *idev; - struct ucb1x00 *ucb; - - spinlock_t irq_lock; - unsigned irq_disabled; - wait_queue_head_t irq_wait; - struct task_struct *rtask; - u16 x_res; - u16 y_res; - - unsigned int adcsync:1; -}; - -static int adcsync; - -static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) -{ - struct input_dev *idev = ts->idev; - - input_report_abs(idev, ABS_X, x); - input_report_abs(idev, ABS_Y, y); - input_report_abs(idev, ABS_PRESSURE, pressure); - input_report_key(idev, BTN_TOUCH, 1); - input_sync(idev); -} - -static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) -{ - struct input_dev *idev = ts->idev; - - input_report_abs(idev, ABS_PRESSURE, 0); - input_report_key(idev, BTN_TOUCH, 0); - input_sync(idev); -} - -/* - * Switch to interrupt mode. - */ -static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_INT); -} - -/* - * Switch to pressure mode, and read pressure. We don't need to wait - * here, since both plates are being driven. - */ -static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) { - ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync); - } else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); - } -} - -/* - * Switch to X position mode and measure Y plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) - ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK); - else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - } - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); -} - -/* - * Switch to Y position mode and measure X plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) - ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK); - else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - } - - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync); -} - -/* - * Switch to X plate resistance mode. Set MX to ground, PX to - * supply. Measure current. - */ -static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -} - -/* - * Switch to Y plate resistance mode. Set MY to ground, PY to - * supply. Measure current. - */ -static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -} - -static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts) -{ - unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR); - - if (machine_is_collie()) - return (!(val & (UCB_TS_CR_TSPX_LOW))); - else - return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)); -} - -/* - * This is a RT kernel thread that handles the ADC accesses - * (mainly so we can use semaphores in the UCB1200 core code - * to serialise accesses to the ADC). - */ -static int ucb1x00_thread(void *_ts) -{ - struct ucb1x00_ts *ts = _ts; - DECLARE_WAITQUEUE(wait, current); - bool frozen, ignore = false; - int valid = 0; - - set_freezable(); - add_wait_queue(&ts->irq_wait, &wait); - while (!kthread_freezable_should_stop(&frozen)) { - unsigned int x, y, p; - signed long timeout; - - if (frozen) - ignore = true; - - ucb1x00_adc_enable(ts->ucb); - - x = ucb1x00_ts_read_xpos(ts); - y = ucb1x00_ts_read_ypos(ts); - p = ucb1x00_ts_read_pressure(ts); - - /* - * Switch back to interrupt mode. - */ - ucb1x00_ts_mode_int(ts); - ucb1x00_adc_disable(ts->ucb); - - msleep(10); - - ucb1x00_enable(ts->ucb); - - - if (ucb1x00_ts_pen_down(ts)) { - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(&ts->irq_lock); - if (ts->irq_disabled) { - ts->irq_disabled = 0; - enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX); - } - spin_unlock_irq(&ts->irq_lock); - ucb1x00_disable(ts->ucb); - - /* - * If we spat out a valid sample set last time, - * spit out a "pen off" sample here. - */ - if (valid) { - ucb1x00_ts_event_release(ts); - valid = 0; - } - - timeout = MAX_SCHEDULE_TIMEOUT; - } else { - ucb1x00_disable(ts->ucb); - - /* - * Filtering is policy. Policy belongs in user - * space. We therefore leave it to user space - * to do any filtering they please. - */ - if (!ignore) { - ucb1x00_ts_evt_add(ts, p, x, y); - valid = 1; - } - - set_current_state(TASK_INTERRUPTIBLE); - timeout = HZ / 100; - } - - schedule_timeout(timeout); - } - - remove_wait_queue(&ts->irq_wait, &wait); - - ts->rtask = NULL; - return 0; -} - -/* - * We only detect touch screen _touches_ with this interrupt - * handler, and even then we just schedule our task. - */ -static irqreturn_t ucb1x00_ts_irq(int irq, void *id) -{ - struct ucb1x00_ts *ts = id; - - spin_lock(&ts->irq_lock); - ts->irq_disabled = 1; - disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX); - spin_unlock(&ts->irq_lock); - wake_up(&ts->irq_wait); - - return IRQ_HANDLED; -} - -static int ucb1x00_ts_open(struct input_dev *idev) -{ - struct ucb1x00_ts *ts = input_get_drvdata(idev); - unsigned long flags = 0; - int ret = 0; - - BUG_ON(ts->rtask); - - if (machine_is_collie()) - flags = IRQF_TRIGGER_RISING; - else - flags = IRQF_TRIGGER_FALLING; - - ts->irq_disabled = 0; - - init_waitqueue_head(&ts->irq_wait); - ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq, - flags, "ucb1x00-ts", ts); - if (ret < 0) - goto out; - - /* - * If we do this at all, we should allow the user to - * measure and read the X and Y resistance at any time. - */ - ucb1x00_adc_enable(ts->ucb); - ts->x_res = ucb1x00_ts_read_xres(ts); - ts->y_res = ucb1x00_ts_read_yres(ts); - ucb1x00_adc_disable(ts->ucb); - - ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd"); - if (!IS_ERR(ts->rtask)) { - ret = 0; - } else { - free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts); - ts->rtask = NULL; - ret = -EFAULT; - } - - out: - return ret; -} - -/* - * Release touchscreen resources. Disable IRQs. - */ -static void ucb1x00_ts_close(struct input_dev *idev) -{ - struct ucb1x00_ts *ts = input_get_drvdata(idev); - - if (ts->rtask) - kthread_stop(ts->rtask); - - ucb1x00_enable(ts->ucb); - free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0); - ucb1x00_disable(ts->ucb); -} - - -/* - * Initialisation. - */ -static int ucb1x00_ts_add(struct ucb1x00_dev *dev) -{ - struct ucb1x00_ts *ts; - struct input_dev *idev; - int err; - - ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); - idev = input_allocate_device(); - if (!ts || !idev) { - err = -ENOMEM; - goto fail; - } - - ts->ucb = dev->ucb; - ts->idev = idev; - ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; - spin_lock_init(&ts->irq_lock); - - idev->name = "Touchscreen panel"; - idev->id.product = ts->ucb->id; - idev->open = ucb1x00_ts_open; - idev->close = ucb1x00_ts_close; - idev->dev.parent = &ts->ucb->dev; - - idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); - idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - - input_set_drvdata(idev, ts); - - ucb1x00_adc_enable(ts->ucb); - ts->x_res = ucb1x00_ts_read_xres(ts); - ts->y_res = ucb1x00_ts_read_yres(ts); - ucb1x00_adc_disable(ts->ucb); - - input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); - input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); - input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); - - err = input_register_device(idev); - if (err) - goto fail; - - dev->priv = ts; - - return 0; - - fail: - input_free_device(idev); - kfree(ts); - return err; -} - -static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) -{ - struct ucb1x00_ts *ts = dev->priv; - - input_unregister_device(ts->idev); - kfree(ts); -} - -static struct ucb1x00_driver ucb1x00_ts_driver = { - .add = ucb1x00_ts_add, - .remove = ucb1x00_ts_remove, -}; - -static int __init ucb1x00_ts_init(void) -{ - return ucb1x00_register_driver(&ucb1x00_ts_driver); -} - -static void __exit ucb1x00_ts_exit(void) -{ - ucb1x00_unregister_driver(&ucb1x00_ts_driver); -} - -module_param(adcsync, int, 0444); -module_init(ucb1x00_ts_init); -module_exit(ucb1x00_ts_exit); - -MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); -MODULE_DESCRIPTION("UCB1x00 touchscreen driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/vt1603-core.c b/ANDROID_3.4.5/drivers/mfd/vt1603-core.c deleted file mode 100755 index 965d7881..00000000 --- a/ANDROID_3.4.5/drivers/mfd/vt1603-core.c +++ /dev/null @@ -1,472 +0,0 @@ -/*++ - * WonderMedia core driver for VT1603/VT1609 - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 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, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/platform_device.h> -#include <linux/err.h> -#include <linux/mfd/core.h> -#include <linux/regulator/consumer.h> -#include <linux/regulator/machine.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/spi/spi.h> -#include <linux/mfd/vt1603/core.h> - -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - -int vt1603_reg_write(struct vt1603 *vt1603, u8 reg, u8 val) -{ - return vt1603->reg_write(vt1603, reg, val); -} - -int vt1603_reg_read(struct vt1603 *vt1603, u8 reg, u8 *val) -{ - return vt1603->reg_read(vt1603, reg, val); -} - -void vt1603_regs_dump(struct vt1603 *vt1603) -{ - int reg, ret; - u8 val; - pr_info("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - for (reg = 0; reg < 0xe8; reg++) { - ret = vt1603->reg_read(vt1603, reg, &val); - if (ret) { - pr_err("\nvt1603_hw_read[r:%d] error\n", reg); - goto out; - } - if(reg%4 == 0) - pr_info("\n"); - pr_info("reg[%02x]=%02x ", reg, val); - } -out: - pr_info("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); -} - -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ - -static int vt1603_mfd_init(struct vt1603 *vt1603) -{ - int ret; - struct mfd_cell cell[] = { - { - .name = "vt1603-codec", - .platform_data = vt1603, - .pdata_size = sizeof(*vt1603), - }, - { - .name = "vt1603-touch", - .platform_data = vt1603, - .pdata_size = sizeof(*vt1603), - }, - { - .name = "vt1603-batt", - .platform_data = vt1603, - .pdata_size = sizeof(*vt1603), - }, - }; - - ret = mfd_add_devices(vt1603->dev, -1, - cell, ARRAY_SIZE(cell), - NULL, 0); - if (ret != 0) { - pr_err("vt1603_mfd_init error: %d\n", ret); - goto err; - } - return 0; - -err: - mfd_remove_devices(vt1603->dev); - kfree(vt1603); - return ret; -} - -static void vt1603_mfd_release(struct vt1603 *vt1603) -{ - mfd_remove_devices(vt1603->dev); - kfree(vt1603); -} - -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ - -#if defined(CONFIG_I2C) /*&& defined(CONFIG_VT1603_IOCTRL_I2C) */ -static int vt1603_i2c_write(struct vt1603 *vt1603, u8 reg, u8 val) -{ - int ret; - struct i2c_client *i2c = vt1603->control_data; - struct i2c_msg xfer[1]; - u8 buf[2]; - - /* - * [MSG1]: fill the register address data - * fill the data Tx buffer - */ - xfer[0].addr = i2c->addr; - xfer[0].len = 2; - xfer[0].flags = 0 ; - xfer[0].flags &= ~(I2C_M_RD); - xfer[0].buf = buf; - buf[0] = reg; - buf[1] = val; - ret = i2c_transfer(i2c->adapter, xfer, ARRAY_SIZE(xfer)); - - /* i2c_transfer returns number of messages transferred */ - if (ret != ARRAY_SIZE(xfer)) { - pr_err("vt1603_i2c_read[r:%d, v:%d] errcode[%d]\n", reg, val, ret); - if (ret < 0) - return ret; - else - return -EIO; - } else - return 0; -} - -static int vt1603_i2c_read(struct vt1603 *vt1603, u8 reg, u8 *val) -{ - int ret; - struct i2c_client *i2c = vt1603->control_data; - struct i2c_msg xfer[2]; - - /* [MSG1] fill the register address data */ - xfer[0].addr = i2c->addr; - xfer[0].len = 1; - xfer[0].flags = 0| I2C_M_NOSTART; //2; /* Read the register val */ //modify 2014-1-20 - xfer[0].buf = ® - /* [MSG2] fill the data rx buffer */ - xfer[1].addr = i2c->addr; - xfer[1].flags = I2C_M_RD; /* Read the register val */ - xfer[1].len = 1; /* only n bytes */ - xfer[1].buf = val; - ret = i2c_transfer(i2c->adapter, xfer, ARRAY_SIZE(xfer)); - - /* i2c_transfer returns number of messages transferred */ - if (ret != ARRAY_SIZE(xfer)) { - pr_err("vt1603_i2c_read[r:%d] errcode[%d]\n", reg, ret); - if (ret < 0) - return ret; - else - return -EIO; - } else { - return 0; - } -} - -static int __devinit vt1603_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct vt1603 *vt1603; - - if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C) == 0) { - pr_err("vt1603_i2c_probe: can't talk I2C?\n"); - return -EIO; - } - - vt1603 = kzalloc(sizeof(struct vt1603), GFP_KERNEL); - if (vt1603 == NULL) - return -ENOMEM; - - vt1603->dev = &i2c->dev; - vt1603->control_data = i2c; - vt1603->reg_read = vt1603_i2c_read; - vt1603->reg_write = vt1603_i2c_write; - vt1603->type = id->driver_data; - i2c_set_clientdata(i2c, vt1603); - dev_set_drvdata(vt1603->dev, vt1603); - - return vt1603_mfd_init(vt1603); -} - -static int __devexit vt1603_i2c_remove(struct i2c_client *i2c) -{ - struct vt1603 *vt1603 = i2c_get_clientdata(i2c); - vt1603_mfd_release(vt1603); - return 0; -} - -static const struct i2c_device_id vt1603_i2c_id[] = { - { "vt1603", VT1603 }, - { "vt1609", VT1609 }, -}; -MODULE_DEVICE_TABLE(i2c, vt1603_i2c_id); - -/* corgi i2c codec control layer */ -static struct i2c_driver vt1603_i2c_driver = { - .driver = { - .name = "VT1603", - .owner = THIS_MODULE, - }, - .probe = vt1603_i2c_probe, - .remove = __devexit_p(vt1603_i2c_remove), - .id_table = vt1603_i2c_id, -}; -#endif - -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ - -#if defined(CONFIG_SPI_MASTER) && defined(CONFIG_VT1603_IOCTRL_SPI) -static int vt1603_spi_write_then_read(struct spi_device *spi, - const u8 *txbuf, unsigned n_tx, - u8 *rxbuf, unsigned n_rx) -{ - static DEFINE_MUTEX(lock); - static u8 buf[32]; - - int status; - struct spi_message message; - struct spi_transfer x; - u8 *local_buf; - - /* Use preallocated DMA-safe buffer. We can't avoid copying here, - * (as a pure convenience thing), but we can keep heap costs - * out of the hot path ... - */ - if ((n_tx + n_rx) > ARRAY_SIZE(buf)) - return -EINVAL; - - spi_message_init(&message); - memset(&x, 0, sizeof x); - x.len = n_tx + n_rx; - spi_message_add_tail(&x, &message); - - /* ... unless someone else is using the pre-allocated buffer */ - if (!mutex_trylock(&lock)) { - local_buf = kmalloc(ARRAY_SIZE(buf), GFP_KERNEL); - if (!local_buf) - return -ENOMEM; - } - else { - memset(buf, 0x00, sizeof(buf)); - local_buf = buf; - } - - memcpy(local_buf, txbuf, n_tx); - x.tx_buf = local_buf; - x.rx_buf = local_buf; - - /* do the i/o */ - status = spi_sync(spi, &message); - if (status == 0) - memcpy(rxbuf, x.rx_buf + n_tx, n_rx); - - if (x.tx_buf == buf) - mutex_unlock(&lock); - else - kfree(local_buf); - - return status; -} - -static int vt1603_spi_write(struct vt1603 *vt1603, u8 reg, u8 val) -{ - int ret = 0; - u8 xfer[3] = { 0 }; - struct spi_device *spi = vt1603->control_data; - - xfer[0] = ((reg & 0xff) | 0x80); - xfer[1] = ((reg & 0xff) >> 7); - xfer[2] = val & 0xff; - ret = spi_write(spi, xfer, ARRAY_SIZE(xfer)); - if (ret != 0) - pr_err("vt1603_spi_write[r:%d, v:%d] errcode[%d]\n", reg, val, ret); - - return ret; -} - -static int vt1603_spi_read(struct vt1603 *vt1603, u8 reg, u8 *val) -{ - u8 addr[3] = { 0 }; - u8 data[3] = { 0 }; - int ret = 0; - struct spi_device *spi = vt1603->control_data; - - addr[0] = ((reg & 0xff) & (~ 0x80)); - addr[1] = ((reg & 0xff) >> 7); - addr[2] = 0xff; - ret = vt1603_spi_write_then_read(spi, addr, 2, data, 3); - if(ret != 0) - pr_err("vt1603_spi_read[r:%d] errcode[%d]\n", reg, ret); - - *val = data[2]; - return ret; -} - -static int vt1603_spi_probe(struct spi_device *spi ) -{ - struct vt1603 *vt1603; - const struct spi_device_id *id = spi_get_device_id(spi); - - vt1603 = kzalloc(sizeof(struct vt1603), GFP_KERNEL); - if (vt1603 == NULL) - return -ENOMEM; - - vt1603->dev = &spi->dev; - vt1603->control_data = spi; - vt1603->reg_read = vt1603_spi_read; - vt1603->reg_write = vt1603_spi_write; - vt1603->type = id->driver_data; - - spi_set_drvdata(spi, vt1603); - dev_set_drvdata(vt1603->dev, vt1603); - - return vt1603_mfd_init(vt1603); -} - -static int vt1603_spi_remove(struct spi_device *spi) -{ - struct vt1603 *vt1603 = spi_get_drvdata(spi); - vt1603_mfd_release(vt1603); - return 0; -} - -static const struct spi_device_id vt1603_spi_id[] = { - { "vt1603", VT1603}, - { "vt1609", VT1609}, -}; -MODULE_DEVICE_TABLE(spi, vt1603_spi_id); - -static struct spi_driver vt1603_spi_driver = { - .driver = { - .name = "VT1603", - .owner = THIS_MODULE, - }, - .probe = vt1603_spi_probe, - .remove = __devexit_p(vt1603_spi_remove), - .id_table = vt1603_spi_id, -}; -#endif - - -static struct i2c_board_info vt1603_i2c_board_info = { - .type = "vt1603", //VT1603 - .flags = 0x00, - .addr = 0x1a,//0x1a, 0x05 err -5 IOerr - .platform_data = NULL, - .archdata = NULL, - .irq = -1, -}; -static int g_i2c_no = 0; -static int g_i2c_cotrol = 0; -static int vt1603_i2c_register_device (void) -{ - struct i2c_board_info *vt1603_i2c_bi; - struct i2c_adapter *adapter = NULL; - struct i2c_client *l_client = NULL; - - //struct i2c_client *client = NULL; - vt1603_i2c_bi = &vt1603_i2c_board_info; - adapter = i2c_get_adapter(g_i2c_no);/*in bus 0*/ - - if (NULL == adapter) { - printk("can not get i2c adapter, client address error\n"); - return -1; - } - l_client = i2c_new_device(adapter, vt1603_i2c_bi); - if (l_client == NULL) { - printk("allocate i2c client failed\n"); - return -1; - } - i2c_put_adapter(adapter); - return 0; -} -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ - -static int __init vt1603_init(void) -{ - int ret = -1; - - char buf[100]; - int varlen = sizeof(buf);// - int bus = 0; - int no = 0; - //int i2c_control = 0; - //int i2c_no = 0; - - memset(buf, 0, 100); - printk("<<<%s wmt.vt1603.bus\n", __func__); - ret = wmt_getsyspara("wmt.vt1603.bus", buf, &varlen); - - if (ret == 0) - { - printk("<<<%s wmt.vt1603.bus:%s\n",__func__, buf); - //i2c---->0x1 spi--->0x0 - sscanf(buf, "%d:%d", &bus, &no); - if (bus > 0) { - g_i2c_cotrol = 1; - //i2c_no = no; - g_i2c_no = no; - } - } -#if defined(CONFIG_I2C) /*&& defined(CONFIG_VT1603_IOCTRL_I2C) */ - if (g_i2c_cotrol) { - - vt1603_i2c_register_device(); - ret = i2c_add_driver(&vt1603_i2c_driver); - if (ret != 0) - pr_err("Failed to register vt1603 I2C driver: %d\n", ret); - - printk("<<<<<%s using i2c bus\n", __func__); - return 0; - } -#endif -#if defined(CONFIG_SPI_MASTER) && defined(CONFIG_VT1603_IOCTRL_SPI) - ret = spi_register_driver(&vt1603_spi_driver); - if (ret != 0) - pr_err("Failed to register vt1603 SPI driver: %d\n", ret); - - printk("<<<<<%s using spi bus\n", __func__); -#endif - return ret; -} -module_init(vt1603_init); - -static void __exit vt1603_exit(void) -{ -#if defined(CONFIG_I2C) /*&& defined(CONFIG_VT1603_IOCTRL_I2C) */ - if (g_i2c_cotrol) - i2c_del_driver(&vt1603_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) && defined(CONFIG_VT1603_IOCTRL_SPI) - spi_unregister_driver(&vt1603_spi_driver); -#endif -} -module_exit(vt1603_exit); - - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_LICENSE("GPL");
\ No newline at end of file diff --git a/ANDROID_3.4.5/drivers/mfd/vx855.c b/ANDROID_3.4.5/drivers/mfd/vx855.c deleted file mode 100644 index b73cc15e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/vx855.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Linux multi-function-device driver (MFD) for the integrated peripherals - * of the VIA VX855 chipset - * - * Copyright (C) 2009 VIA Technologies, Inc. - * Copyright (C) 2010 One Laptop per Child - * Author: Harald Welte <HaraldWelte@viatech.com> - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/pci.h> -#include <linux/mfd/core.h> - -/* offset into pci config space indicating the 16bit register containing - * the power management IO space base */ -#define VX855_CFG_PMIO_OFFSET 0x88 - -/* ACPI I/O Space registers */ -#define VX855_PMIO_ACPI 0x00 -#define VX855_PMIO_ACPI_LEN 0x0b - -/* Processor Power Management */ -#define VX855_PMIO_PPM 0x10 -#define VX855_PMIO_PPM_LEN 0x08 - -/* General Purpose Power Management */ -#define VX855_PMIO_GPPM 0x20 -#define VX855_PMIO_R_GPI 0x48 -#define VX855_PMIO_R_GPO 0x4c -#define VX855_PMIO_GPPM_LEN 0x33 - -#define VSPIC_MMIO_SIZE 0x1000 - -static struct resource vx855_gpio_resources[] = { - { - .flags = IORESOURCE_IO, - }, - { - .flags = IORESOURCE_IO, - }, -}; - -static struct mfd_cell vx855_cells[] = { - { - .name = "vx855_gpio", - .num_resources = ARRAY_SIZE(vx855_gpio_resources), - .resources = vx855_gpio_resources, - - /* we must ignore resource conflicts, for reasons outlined in - * the vx855_gpio driver */ - .ignore_resource_conflicts = true, - }, -}; - -static __devinit int vx855_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int ret; - u16 gpio_io_offset; - - ret = pci_enable_device(pdev); - if (ret) - return -ENODEV; - - pci_read_config_word(pdev, VX855_CFG_PMIO_OFFSET, &gpio_io_offset); - if (!gpio_io_offset) { - dev_warn(&pdev->dev, - "BIOS did not assign PMIO base offset?!?\n"); - ret = -ENODEV; - goto out; - } - - /* mask out the lowest seven bits, as they are always zero, but - * hardware returns them as 0x01 */ - gpio_io_offset &= 0xff80; - - /* As the region identified here includes many non-GPIO things, we - * only work with the specific registers that concern us. */ - vx855_gpio_resources[0].start = gpio_io_offset + VX855_PMIO_R_GPI; - vx855_gpio_resources[0].end = vx855_gpio_resources[0].start + 3; - vx855_gpio_resources[1].start = gpio_io_offset + VX855_PMIO_R_GPO; - vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; - - ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), - NULL, 0); - - /* we always return -ENODEV here in order to enable other - * drivers like old, not-yet-platform_device ported i2c-viapro */ - return -ENODEV; -out: - pci_disable_device(pdev); - return ret; -} - -static void __devexit vx855_remove(struct pci_dev *pdev) -{ - mfd_remove_devices(&pdev->dev); - pci_disable_device(pdev); -} - -static DEFINE_PCI_DEVICE_TABLE(vx855_pci_tbl) = { - { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, vx855_pci_tbl); - -static struct pci_driver vx855_pci_driver = { - .name = "vx855", - .id_table = vx855_pci_tbl, - .probe = vx855_probe, - .remove = __devexit_p(vx855_remove), -}; - -static int vx855_init(void) -{ - return pci_register_driver(&vx855_pci_driver); -} -module_init(vx855_init); - -static void vx855_exit(void) -{ - pci_unregister_driver(&vx855_pci_driver); -} -module_exit(vx855_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte <HaraldWelte@viatech.com>"); -MODULE_DESCRIPTION("Driver for the VIA VX855 chipset"); diff --git a/ANDROID_3.4.5/drivers/mfd/wl1273-core.c b/ANDROID_3.4.5/drivers/mfd/wl1273-core.c deleted file mode 100644 index f39b756d..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wl1273-core.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * MFD driver for wl1273 FM radio and audio codec submodules. - * - * Copyright (C) 2011 Nokia Corporation - * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <linux/mfd/wl1273-core.h> -#include <linux/slab.h> -#include <linux/module.h> - -#define DRIVER_DESC "WL1273 FM Radio Core" - -static const struct i2c_device_id wl1273_driver_id_table[] = { - { WL1273_FM_DRIVER_NAME, 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table); - -static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value) -{ - struct i2c_client *client = core->client; - u8 b[2]; - int r; - - r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b); - if (r != 2) { - dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg); - return -EREMOTEIO; - } - - *value = (u16)b[0] << 8 | b[1]; - - return 0; -} - -static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param) -{ - struct i2c_client *client = core->client; - u8 buf[] = { (param >> 8) & 0xff, param & 0xff }; - int r; - - r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf); - if (r) { - dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd); - return r; - } - - return 0; -} - -static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len) -{ - struct i2c_client *client = core->client; - struct i2c_msg msg; - int r; - - msg.addr = client->addr; - msg.flags = 0; - msg.buf = data; - msg.len = len; - - r = i2c_transfer(client->adapter, &msg, 1); - if (r != 1) { - dev_err(&client->dev, "%s: write error.\n", __func__); - return -EREMOTEIO; - } - - return 0; -} - -/** - * wl1273_fm_set_audio() - Set audio mode. - * @core: A pointer to the device struct. - * @new_mode: The new audio mode. - * - * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG. - */ -static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode) -{ - int r = 0; - - if (core->mode == WL1273_MODE_OFF || - core->mode == WL1273_MODE_SUSPENDED) - return -EPERM; - - if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) { - r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET, - WL1273_PCM_DEF_MODE); - if (r) - goto out; - - r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET, - core->i2s_mode); - if (r) - goto out; - - r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE, - WL1273_AUDIO_ENABLE_I2S); - if (r) - goto out; - - } else if (core->mode == WL1273_MODE_RX && - new_mode == WL1273_AUDIO_ANALOG) { - r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE, - WL1273_AUDIO_ENABLE_ANALOG); - if (r) - goto out; - - } else if (core->mode == WL1273_MODE_TX && - new_mode == WL1273_AUDIO_DIGITAL) { - r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET, - core->i2s_mode); - if (r) - goto out; - - r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET, - WL1273_AUDIO_IO_SET_I2S); - if (r) - goto out; - - } else if (core->mode == WL1273_MODE_TX && - new_mode == WL1273_AUDIO_ANALOG) { - r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET, - WL1273_AUDIO_IO_SET_ANALOG); - if (r) - goto out; - } - - core->audio_mode = new_mode; -out: - return r; -} - -/** - * wl1273_fm_set_volume() - Set volume. - * @core: A pointer to the device struct. - * @volume: The new volume value. - */ -static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume) -{ - int r; - - if (volume > WL1273_MAX_VOLUME) - return -EINVAL; - - if (core->volume == volume) - return 0; - - r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume); - if (r) - return r; - - core->volume = volume; - return 0; -} - -static int wl1273_core_remove(struct i2c_client *client) -{ - struct wl1273_core *core = i2c_get_clientdata(client); - - dev_dbg(&client->dev, "%s\n", __func__); - - mfd_remove_devices(&client->dev); - kfree(core); - - return 0; -} - -static int __devinit wl1273_core_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct wl1273_fm_platform_data *pdata = client->dev.platform_data; - struct wl1273_core *core; - struct mfd_cell *cell; - int children = 0; - int r = 0; - - dev_dbg(&client->dev, "%s\n", __func__); - - if (!pdata) { - dev_err(&client->dev, "No platform data.\n"); - return -EINVAL; - } - - if (!(pdata->children & WL1273_RADIO_CHILD)) { - dev_err(&client->dev, "Cannot function without radio child.\n"); - return -EINVAL; - } - - core = kzalloc(sizeof(*core), GFP_KERNEL); - if (!core) - return -ENOMEM; - - core->pdata = pdata; - core->client = client; - mutex_init(&core->lock); - - i2c_set_clientdata(client, core); - - dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__); - - cell = &core->cells[children]; - cell->name = "wl1273_fm_radio"; - cell->platform_data = &core; - cell->pdata_size = sizeof(core); - children++; - - core->read = wl1273_fm_read_reg; - core->write = wl1273_fm_write_cmd; - core->write_data = wl1273_fm_write_data; - core->set_audio = wl1273_fm_set_audio; - core->set_volume = wl1273_fm_set_volume; - - if (pdata->children & WL1273_CODEC_CHILD) { - cell = &core->cells[children]; - - dev_dbg(&client->dev, "%s: Have codec.\n", __func__); - cell->name = "wl1273-codec"; - cell->platform_data = &core; - cell->pdata_size = sizeof(core); - children++; - } - - dev_dbg(&client->dev, "%s: number of children: %d.\n", - __func__, children); - - r = mfd_add_devices(&client->dev, -1, core->cells, - children, NULL, 0); - if (r) - goto err; - - return 0; - -err: - pdata->free_resources(); - kfree(core); - - dev_dbg(&client->dev, "%s\n", __func__); - - return r; -} - -static struct i2c_driver wl1273_core_driver = { - .driver = { - .name = WL1273_FM_DRIVER_NAME, - }, - .probe = wl1273_core_probe, - .id_table = wl1273_driver_id_table, - .remove = __devexit_p(wl1273_core_remove), -}; - -static int __init wl1273_core_init(void) -{ - int r; - - r = i2c_add_driver(&wl1273_core_driver); - if (r) { - pr_err(WL1273_FM_DRIVER_NAME - ": driver registration failed\n"); - return r; - } - - return r; -} - -static void __exit wl1273_core_exit(void) -{ - i2c_del_driver(&wl1273_core_driver); -} -late_initcall(wl1273_core_init); -module_exit(wl1273_core_exit); - -MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-auxadc.c b/ANDROID_3.4.5/drivers/mfd/wm831x-auxadc.c deleted file mode 100644 index 87210954..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-auxadc.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * wm831x-auxadc.c -- AUXADC for Wolfson WM831x PMICs - * - * Copyright 2009-2011 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/mfd/core.h> -#include <linux/slab.h> -#include <linux/list.h> - -#include <linux/mfd/wm831x/core.h> -#include <linux/mfd/wm831x/pdata.h> -#include <linux/mfd/wm831x/irq.h> -#include <linux/mfd/wm831x/auxadc.h> -#include <linux/mfd/wm831x/otp.h> -#include <linux/mfd/wm831x/regulator.h> - -struct wm831x_auxadc_req { - struct list_head list; - enum wm831x_auxadc input; - int val; - struct completion done; -}; - -static int wm831x_auxadc_read_irq(struct wm831x *wm831x, - enum wm831x_auxadc input) -{ - struct wm831x_auxadc_req *req; - int ret; - bool ena = false; - - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - - init_completion(&req->done); - req->input = input; - req->val = -ETIMEDOUT; - - mutex_lock(&wm831x->auxadc_lock); - - /* Enqueue the request */ - list_add(&req->list, &wm831x->auxadc_pending); - - ena = !wm831x->auxadc_active; - - if (ena) { - ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, - WM831X_AUX_ENA, WM831X_AUX_ENA); - if (ret != 0) { - dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", - ret); - goto out; - } - } - - /* Enable the conversion if not already running */ - if (!(wm831x->auxadc_active & (1 << input))) { - ret = wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE, - 1 << input, 1 << input); - if (ret != 0) { - dev_err(wm831x->dev, - "Failed to set AUXADC source: %d\n", ret); - goto out; - } - - wm831x->auxadc_active |= 1 << input; - } - - /* We convert at the fastest rate possible */ - if (ena) { - ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, - WM831X_AUX_CVT_ENA | - WM831X_AUX_RATE_MASK, - WM831X_AUX_CVT_ENA | - WM831X_AUX_RATE_MASK); - if (ret != 0) { - dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", - ret); - goto out; - } - } - - mutex_unlock(&wm831x->auxadc_lock); - - /* Wait for an interrupt */ - wait_for_completion_timeout(&req->done, msecs_to_jiffies(500)); - - mutex_lock(&wm831x->auxadc_lock); - - list_del(&req->list); - ret = req->val; - -out: - mutex_unlock(&wm831x->auxadc_lock); - - kfree(req); - - return ret; -} - -static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) -{ - struct wm831x *wm831x = irq_data; - struct wm831x_auxadc_req *req; - int ret, input, val; - - ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); - if (ret < 0) { - dev_err(wm831x->dev, - "Failed to read AUXADC data: %d\n", ret); - return IRQ_NONE; - } - - input = ((ret & WM831X_AUX_DATA_SRC_MASK) - >> WM831X_AUX_DATA_SRC_SHIFT) - 1; - - if (input == 14) - input = WM831X_AUX_CAL; - - val = ret & WM831X_AUX_DATA_MASK; - - mutex_lock(&wm831x->auxadc_lock); - - /* Disable this conversion, we're about to complete all users */ - wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE, - 1 << input, 0); - wm831x->auxadc_active &= ~(1 << input); - - /* Turn off the entire convertor if idle */ - if (!wm831x->auxadc_active) - wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0); - - /* Wake up any threads waiting for this request */ - list_for_each_entry(req, &wm831x->auxadc_pending, list) { - if (req->input == input) { - req->val = val; - complete(&req->done); - } - } - - mutex_unlock(&wm831x->auxadc_lock); - - return IRQ_HANDLED; -} - -static int wm831x_auxadc_read_polled(struct wm831x *wm831x, - enum wm831x_auxadc input) -{ - int ret, src, timeout; - - mutex_lock(&wm831x->auxadc_lock); - - ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, - WM831X_AUX_ENA, WM831X_AUX_ENA); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret); - goto out; - } - - /* We force a single source at present */ - src = input; - ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE, - 1 << src); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret); - goto out; - } - - ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, - WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret); - goto disable; - } - - /* If we're not using interrupts then poll the - * interrupt status register */ - timeout = 5; - while (timeout) { - msleep(1); - - ret = wm831x_reg_read(wm831x, - WM831X_INTERRUPT_STATUS_1); - if (ret < 0) { - dev_err(wm831x->dev, - "ISR 1 read failed: %d\n", ret); - goto disable; - } - - /* Did it complete? */ - if (ret & WM831X_AUXADC_DATA_EINT) { - wm831x_reg_write(wm831x, - WM831X_INTERRUPT_STATUS_1, - WM831X_AUXADC_DATA_EINT); - break; - } else { - dev_err(wm831x->dev, - "AUXADC conversion timeout\n"); - ret = -EBUSY; - goto disable; - } - } - - ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); - if (ret < 0) { - dev_err(wm831x->dev, - "Failed to read AUXADC data: %d\n", ret); - goto disable; - } - - src = ((ret & WM831X_AUX_DATA_SRC_MASK) - >> WM831X_AUX_DATA_SRC_SHIFT) - 1; - - if (src == 14) - src = WM831X_AUX_CAL; - - if (src != input) { - dev_err(wm831x->dev, "Data from source %d not %d\n", - src, input); - ret = -EINVAL; - } else { - ret &= WM831X_AUX_DATA_MASK; - } - -disable: - wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0); -out: - mutex_unlock(&wm831x->auxadc_lock); - return ret; -} - -/** - * wm831x_auxadc_read: Read a value from the WM831x AUXADC - * - * @wm831x: Device to read from. - * @input: AUXADC input to read. - */ -int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) -{ - return wm831x->auxadc_read(wm831x, input); -} -EXPORT_SYMBOL_GPL(wm831x_auxadc_read); - -/** - * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC - * - * @wm831x: Device to read from. - * @input: AUXADC input to read. - */ -int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input) -{ - int ret; - - ret = wm831x_auxadc_read(wm831x, input); - if (ret < 0) - return ret; - - ret *= 1465; - - return ret; -} -EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv); - -void wm831x_auxadc_init(struct wm831x *wm831x) -{ - int ret; - - mutex_init(&wm831x->auxadc_lock); - INIT_LIST_HEAD(&wm831x->auxadc_pending); - - if (wm831x->irq && wm831x->irq_base) { - wm831x->auxadc_read = wm831x_auxadc_read_irq; - - ret = request_threaded_irq(wm831x->irq_base + - WM831X_IRQ_AUXADC_DATA, - NULL, wm831x_auxadc_irq, 0, - "auxadc", wm831x); - if (ret < 0) { - dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", - ret); - wm831x->auxadc_read = NULL; - } - } - - if (!wm831x->auxadc_read) - wm831x->auxadc_read = wm831x_auxadc_read_polled; -} diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-core.c b/ANDROID_3.4.5/drivers/mfd/wm831x-core.c deleted file mode 100644 index 838056c3..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-core.c +++ /dev/null @@ -1,1938 +0,0 @@ -/* - * wm831x-core.c -- Device access for Wolfson WM831x PMICs - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/bcd.h> -#include <linux/delay.h> -#include <linux/mfd/core.h> -#include <linux/slab.h> -#include <linux/err.h> - -#include <linux/mfd/wm831x/core.h> -#include <linux/mfd/wm831x/pdata.h> -#include <linux/mfd/wm831x/irq.h> -#include <linux/mfd/wm831x/auxadc.h> -#include <linux/mfd/wm831x/otp.h> -#include <linux/mfd/wm831x/pmu.h> -#include <linux/mfd/wm831x/regulator.h> - -/* Current settings - values are 2*2^(reg_val/4) microamps. These are - * exported since they are used by multiple drivers. - */ -int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { - 2, - 2, - 3, - 3, - 4, - 5, - 6, - 7, - 8, - 10, - 11, - 13, - 16, - 19, - 23, - 27, - 32, - 38, - 45, - 54, - 64, - 76, - 91, - 108, - 128, - 152, - 181, - 215, - 256, - 304, - 362, - 431, - 512, - 609, - 724, - 861, - 1024, - 1218, - 1448, - 1722, - 2048, - 2435, - 2896, - 3444, - 4096, - 4871, - 5793, - 6889, - 8192, - 9742, - 11585, - 13777, - 16384, - 19484, - 23170, - 27554, -}; -EXPORT_SYMBOL_GPL(wm831x_isinkv_values); - -static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg) -{ - if (!wm831x->locked) - return 0; - - switch (reg) { - case WM831X_WATCHDOG: - case WM831X_DC4_CONTROL: - case WM831X_ON_PIN_CONTROL: - case WM831X_BACKUP_CHARGER_CONTROL: - case WM831X_CHARGER_CONTROL_1: - case WM831X_CHARGER_CONTROL_2: - return 1; - - default: - return 0; - } -} - -/** - * wm831x_reg_unlock: Unlock user keyed registers - * - * The WM831x has a user key preventing writes to particularly - * critical registers. This function locks those registers, - * allowing writes to them. - */ -void wm831x_reg_lock(struct wm831x *wm831x) -{ - int ret; - - ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0); - if (ret == 0) { - dev_vdbg(wm831x->dev, "Registers locked\n"); - - mutex_lock(&wm831x->io_lock); - WARN_ON(wm831x->locked); - wm831x->locked = 1; - mutex_unlock(&wm831x->io_lock); - } else { - dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret); - } - -} -EXPORT_SYMBOL_GPL(wm831x_reg_lock); - -/** - * wm831x_reg_unlock: Unlock user keyed registers - * - * The WM831x has a user key preventing writes to particularly - * critical registers. This function locks those registers, - * preventing spurious writes. - */ -int wm831x_reg_unlock(struct wm831x *wm831x) -{ - int ret; - - /* 0x9716 is the value required to unlock the registers */ - ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716); - if (ret == 0) { - dev_vdbg(wm831x->dev, "Registers unlocked\n"); - - mutex_lock(&wm831x->io_lock); - WARN_ON(!wm831x->locked); - wm831x->locked = 0; - mutex_unlock(&wm831x->io_lock); - } - - return ret; -} -EXPORT_SYMBOL_GPL(wm831x_reg_unlock); - -static bool wm831x_reg_readable(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM831X_RESET_ID: - case WM831X_REVISION: - case WM831X_PARENT_ID: - case WM831X_SYSVDD_CONTROL: - case WM831X_THERMAL_MONITORING: - case WM831X_POWER_STATE: - case WM831X_WATCHDOG: - case WM831X_ON_PIN_CONTROL: - case WM831X_RESET_CONTROL: - case WM831X_CONTROL_INTERFACE: - case WM831X_SECURITY_KEY: - case WM831X_SOFTWARE_SCRATCH: - case WM831X_OTP_CONTROL: - case WM831X_GPIO_LEVEL: - case WM831X_SYSTEM_STATUS: - case WM831X_ON_SOURCE: - case WM831X_OFF_SOURCE: - case WM831X_SYSTEM_INTERRUPTS: - case WM831X_INTERRUPT_STATUS_1: - case WM831X_INTERRUPT_STATUS_2: - case WM831X_INTERRUPT_STATUS_3: - case WM831X_INTERRUPT_STATUS_4: - case WM831X_INTERRUPT_STATUS_5: - case WM831X_IRQ_CONFIG: - case WM831X_SYSTEM_INTERRUPTS_MASK: - case WM831X_INTERRUPT_STATUS_1_MASK: - case WM831X_INTERRUPT_STATUS_2_MASK: - case WM831X_INTERRUPT_STATUS_3_MASK: - case WM831X_INTERRUPT_STATUS_4_MASK: - case WM831X_INTERRUPT_STATUS_5_MASK: - case WM831X_RTC_WRITE_COUNTER: - case WM831X_RTC_TIME_1: - case WM831X_RTC_TIME_2: - case WM831X_RTC_ALARM_1: - case WM831X_RTC_ALARM_2: - case WM831X_RTC_CONTROL: - case WM831X_RTC_TRIM: - case WM831X_TOUCH_CONTROL_1: - case WM831X_TOUCH_CONTROL_2: - case WM831X_TOUCH_DATA_X: - case WM831X_TOUCH_DATA_Y: - case WM831X_TOUCH_DATA_Z: - case WM831X_AUXADC_DATA: - case WM831X_AUXADC_CONTROL: - case WM831X_AUXADC_SOURCE: - case WM831X_COMPARATOR_CONTROL: - case WM831X_COMPARATOR_1: - case WM831X_COMPARATOR_2: - case WM831X_COMPARATOR_3: - case WM831X_COMPARATOR_4: - case WM831X_GPIO1_CONTROL: - case WM831X_GPIO2_CONTROL: - case WM831X_GPIO3_CONTROL: - case WM831X_GPIO4_CONTROL: - case WM831X_GPIO5_CONTROL: - case WM831X_GPIO6_CONTROL: - case WM831X_GPIO7_CONTROL: - case WM831X_GPIO8_CONTROL: - case WM831X_GPIO9_CONTROL: - case WM831X_GPIO10_CONTROL: - case WM831X_GPIO11_CONTROL: - case WM831X_GPIO12_CONTROL: - case WM831X_GPIO13_CONTROL: - case WM831X_GPIO14_CONTROL: - case WM831X_GPIO15_CONTROL: - case WM831X_GPIO16_CONTROL: - case WM831X_CHARGER_CONTROL_1: - case WM831X_CHARGER_CONTROL_2: - case WM831X_CHARGER_STATUS: - case WM831X_BACKUP_CHARGER_CONTROL: - case WM831X_STATUS_LED_1: - case WM831X_STATUS_LED_2: - case WM831X_CURRENT_SINK_1: - case WM831X_CURRENT_SINK_2: - case WM831X_DCDC_ENABLE: - case WM831X_LDO_ENABLE: - case WM831X_DCDC_STATUS: - case WM831X_LDO_STATUS: - case WM831X_DCDC_UV_STATUS: - case WM831X_LDO_UV_STATUS: - case WM831X_DC1_CONTROL_1: - case WM831X_DC1_CONTROL_2: - case WM831X_DC1_ON_CONFIG: - case WM831X_DC1_SLEEP_CONTROL: - case WM831X_DC1_DVS_CONTROL: - case WM831X_DC2_CONTROL_1: - case WM831X_DC2_CONTROL_2: - case WM831X_DC2_ON_CONFIG: - case WM831X_DC2_SLEEP_CONTROL: - case WM831X_DC2_DVS_CONTROL: - case WM831X_DC3_CONTROL_1: - case WM831X_DC3_CONTROL_2: - case WM831X_DC3_ON_CONFIG: - case WM831X_DC3_SLEEP_CONTROL: - case WM831X_DC4_CONTROL: - case WM831X_DC4_SLEEP_CONTROL: - case WM831X_EPE1_CONTROL: - case WM831X_EPE2_CONTROL: - case WM831X_LDO1_CONTROL: - case WM831X_LDO1_ON_CONTROL: - case WM831X_LDO1_SLEEP_CONTROL: - case WM831X_LDO2_CONTROL: - case WM831X_LDO2_ON_CONTROL: - case WM831X_LDO2_SLEEP_CONTROL: - case WM831X_LDO3_CONTROL: - case WM831X_LDO3_ON_CONTROL: - case WM831X_LDO3_SLEEP_CONTROL: - case WM831X_LDO4_CONTROL: - case WM831X_LDO4_ON_CONTROL: - case WM831X_LDO4_SLEEP_CONTROL: - case WM831X_LDO5_CONTROL: - case WM831X_LDO5_ON_CONTROL: - case WM831X_LDO5_SLEEP_CONTROL: - case WM831X_LDO6_CONTROL: - case WM831X_LDO6_ON_CONTROL: - case WM831X_LDO6_SLEEP_CONTROL: - case WM831X_LDO7_CONTROL: - case WM831X_LDO7_ON_CONTROL: - case WM831X_LDO7_SLEEP_CONTROL: - case WM831X_LDO8_CONTROL: - case WM831X_LDO8_ON_CONTROL: - case WM831X_LDO8_SLEEP_CONTROL: - case WM831X_LDO9_CONTROL: - case WM831X_LDO9_ON_CONTROL: - case WM831X_LDO9_SLEEP_CONTROL: - case WM831X_LDO10_CONTROL: - case WM831X_LDO10_ON_CONTROL: - case WM831X_LDO10_SLEEP_CONTROL: - case WM831X_LDO11_ON_CONTROL: - case WM831X_LDO11_SLEEP_CONTROL: - case WM831X_POWER_GOOD_SOURCE_1: - case WM831X_POWER_GOOD_SOURCE_2: - case WM831X_CLOCK_CONTROL_1: - case WM831X_CLOCK_CONTROL_2: - case WM831X_FLL_CONTROL_1: - case WM831X_FLL_CONTROL_2: - case WM831X_FLL_CONTROL_3: - case WM831X_FLL_CONTROL_4: - case WM831X_FLL_CONTROL_5: - case WM831X_UNIQUE_ID_1: - case WM831X_UNIQUE_ID_2: - case WM831X_UNIQUE_ID_3: - case WM831X_UNIQUE_ID_4: - case WM831X_UNIQUE_ID_5: - case WM831X_UNIQUE_ID_6: - case WM831X_UNIQUE_ID_7: - case WM831X_UNIQUE_ID_8: - case WM831X_FACTORY_OTP_ID: - case WM831X_FACTORY_OTP_1: - case WM831X_FACTORY_OTP_2: - case WM831X_FACTORY_OTP_3: - case WM831X_FACTORY_OTP_4: - case WM831X_FACTORY_OTP_5: - case WM831X_CUSTOMER_OTP_ID: - case WM831X_DC1_OTP_CONTROL: - case WM831X_DC2_OTP_CONTROL: - case WM831X_DC3_OTP_CONTROL: - case WM831X_LDO1_2_OTP_CONTROL: - case WM831X_LDO3_4_OTP_CONTROL: - case WM831X_LDO5_6_OTP_CONTROL: - case WM831X_LDO7_8_OTP_CONTROL: - case WM831X_LDO9_10_OTP_CONTROL: - case WM831X_LDO11_EPE_CONTROL: - case WM831X_GPIO1_OTP_CONTROL: - case WM831X_GPIO2_OTP_CONTROL: - case WM831X_GPIO3_OTP_CONTROL: - case WM831X_GPIO4_OTP_CONTROL: - case WM831X_GPIO5_OTP_CONTROL: - case WM831X_GPIO6_OTP_CONTROL: - case WM831X_DBE_CHECK_DATA: - return true; - default: - return false; - } -} - -static bool wm831x_reg_writeable(struct device *dev, unsigned int reg) -{ - struct wm831x *wm831x = dev_get_drvdata(dev); - - if (wm831x_reg_locked(wm831x, reg)) - return false; - - switch (reg) { - case WM831X_SYSVDD_CONTROL: - case WM831X_THERMAL_MONITORING: - case WM831X_POWER_STATE: - case WM831X_WATCHDOG: - case WM831X_ON_PIN_CONTROL: - case WM831X_RESET_CONTROL: - case WM831X_CONTROL_INTERFACE: - case WM831X_SECURITY_KEY: - case WM831X_SOFTWARE_SCRATCH: - case WM831X_OTP_CONTROL: - case WM831X_GPIO_LEVEL: - case WM831X_INTERRUPT_STATUS_1: - case WM831X_INTERRUPT_STATUS_2: - case WM831X_INTERRUPT_STATUS_3: - case WM831X_INTERRUPT_STATUS_4: - case WM831X_INTERRUPT_STATUS_5: - case WM831X_IRQ_CONFIG: - case WM831X_SYSTEM_INTERRUPTS_MASK: - case WM831X_INTERRUPT_STATUS_1_MASK: - case WM831X_INTERRUPT_STATUS_2_MASK: - case WM831X_INTERRUPT_STATUS_3_MASK: - case WM831X_INTERRUPT_STATUS_4_MASK: - case WM831X_INTERRUPT_STATUS_5_MASK: - case WM831X_RTC_TIME_1: - case WM831X_RTC_TIME_2: - case WM831X_RTC_ALARM_1: - case WM831X_RTC_ALARM_2: - case WM831X_RTC_CONTROL: - case WM831X_RTC_TRIM: - case WM831X_TOUCH_CONTROL_1: - case WM831X_TOUCH_CONTROL_2: - case WM831X_AUXADC_CONTROL: - case WM831X_AUXADC_SOURCE: - case WM831X_COMPARATOR_CONTROL: - case WM831X_COMPARATOR_1: - case WM831X_COMPARATOR_2: - case WM831X_COMPARATOR_3: - case WM831X_COMPARATOR_4: - case WM831X_GPIO1_CONTROL: - case WM831X_GPIO2_CONTROL: - case WM831X_GPIO3_CONTROL: - case WM831X_GPIO4_CONTROL: - case WM831X_GPIO5_CONTROL: - case WM831X_GPIO6_CONTROL: - case WM831X_GPIO7_CONTROL: - case WM831X_GPIO8_CONTROL: - case WM831X_GPIO9_CONTROL: - case WM831X_GPIO10_CONTROL: - case WM831X_GPIO11_CONTROL: - case WM831X_GPIO12_CONTROL: - case WM831X_GPIO13_CONTROL: - case WM831X_GPIO14_CONTROL: - case WM831X_GPIO15_CONTROL: - case WM831X_GPIO16_CONTROL: - case WM831X_CHARGER_CONTROL_1: - case WM831X_CHARGER_CONTROL_2: - case WM831X_CHARGER_STATUS: - case WM831X_BACKUP_CHARGER_CONTROL: - case WM831X_STATUS_LED_1: - case WM831X_STATUS_LED_2: - case WM831X_CURRENT_SINK_1: - case WM831X_CURRENT_SINK_2: - case WM831X_DCDC_ENABLE: - case WM831X_LDO_ENABLE: - case WM831X_DC1_CONTROL_1: - case WM831X_DC1_CONTROL_2: - case WM831X_DC1_ON_CONFIG: - case WM831X_DC1_SLEEP_CONTROL: - case WM831X_DC1_DVS_CONTROL: - case WM831X_DC2_CONTROL_1: - case WM831X_DC2_CONTROL_2: - case WM831X_DC2_ON_CONFIG: - case WM831X_DC2_SLEEP_CONTROL: - case WM831X_DC2_DVS_CONTROL: - case WM831X_DC3_CONTROL_1: - case WM831X_DC3_CONTROL_2: - case WM831X_DC3_ON_CONFIG: - case WM831X_DC3_SLEEP_CONTROL: - case WM831X_DC4_CONTROL: - case WM831X_DC4_SLEEP_CONTROL: - case WM831X_EPE1_CONTROL: - case WM831X_EPE2_CONTROL: - case WM831X_LDO1_CONTROL: - case WM831X_LDO1_ON_CONTROL: - case WM831X_LDO1_SLEEP_CONTROL: - case WM831X_LDO2_CONTROL: - case WM831X_LDO2_ON_CONTROL: - case WM831X_LDO2_SLEEP_CONTROL: - case WM831X_LDO3_CONTROL: - case WM831X_LDO3_ON_CONTROL: - case WM831X_LDO3_SLEEP_CONTROL: - case WM831X_LDO4_CONTROL: - case WM831X_LDO4_ON_CONTROL: - case WM831X_LDO4_SLEEP_CONTROL: - case WM831X_LDO5_CONTROL: - case WM831X_LDO5_ON_CONTROL: - case WM831X_LDO5_SLEEP_CONTROL: - case WM831X_LDO6_CONTROL: - case WM831X_LDO6_ON_CONTROL: - case WM831X_LDO6_SLEEP_CONTROL: - case WM831X_LDO7_CONTROL: - case WM831X_LDO7_ON_CONTROL: - case WM831X_LDO7_SLEEP_CONTROL: - case WM831X_LDO8_CONTROL: - case WM831X_LDO8_ON_CONTROL: - case WM831X_LDO8_SLEEP_CONTROL: - case WM831X_LDO9_CONTROL: - case WM831X_LDO9_ON_CONTROL: - case WM831X_LDO9_SLEEP_CONTROL: - case WM831X_LDO10_CONTROL: - case WM831X_LDO10_ON_CONTROL: - case WM831X_LDO10_SLEEP_CONTROL: - case WM831X_LDO11_ON_CONTROL: - case WM831X_LDO11_SLEEP_CONTROL: - case WM831X_POWER_GOOD_SOURCE_1: - case WM831X_POWER_GOOD_SOURCE_2: - case WM831X_CLOCK_CONTROL_1: - case WM831X_CLOCK_CONTROL_2: - case WM831X_FLL_CONTROL_1: - case WM831X_FLL_CONTROL_2: - case WM831X_FLL_CONTROL_3: - case WM831X_FLL_CONTROL_4: - case WM831X_FLL_CONTROL_5: - return true; - default: - return false; - } -} - -static bool wm831x_reg_volatile(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM831X_SYSTEM_STATUS: - case WM831X_ON_SOURCE: - case WM831X_OFF_SOURCE: - case WM831X_GPIO_LEVEL: - case WM831X_SYSTEM_INTERRUPTS: - case WM831X_INTERRUPT_STATUS_1: - case WM831X_INTERRUPT_STATUS_2: - case WM831X_INTERRUPT_STATUS_3: - case WM831X_INTERRUPT_STATUS_4: - case WM831X_INTERRUPT_STATUS_5: - case WM831X_RTC_TIME_1: - case WM831X_RTC_TIME_2: - case WM831X_TOUCH_DATA_X: - case WM831X_TOUCH_DATA_Y: - case WM831X_TOUCH_DATA_Z: - case WM831X_AUXADC_DATA: - case WM831X_CHARGER_STATUS: - case WM831X_DCDC_STATUS: - case WM831X_LDO_STATUS: - case WM831X_DCDC_UV_STATUS: - case WM831X_LDO_UV_STATUS: - return true; - default: - return false; - } -} - -/** - * wm831x_reg_read: Read a single WM831x register. - * - * @wm831x: Device to read from. - * @reg: Register to read. - */ -int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg) -{ - unsigned int val; - int ret; - - ret = regmap_read(wm831x->regmap, reg, &val); - - if (ret < 0) - return ret; - else - return val; -} -EXPORT_SYMBOL_GPL(wm831x_reg_read); - -/** - * wm831x_bulk_read: Read multiple WM831x registers - * - * @wm831x: Device to read from - * @reg: First register - * @count: Number of registers - * @buf: Buffer to fill. - */ -int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, - int count, u16 *buf) -{ - return regmap_bulk_read(wm831x->regmap, reg, buf, count); -} -EXPORT_SYMBOL_GPL(wm831x_bulk_read); - -static int wm831x_write(struct wm831x *wm831x, unsigned short reg, - int bytes, void *src) -{ - u16 *buf = src; - int i, ret; - - BUG_ON(bytes % 2); - BUG_ON(bytes <= 0); - - for (i = 0; i < bytes / 2; i++) { - if (wm831x_reg_locked(wm831x, reg)) - return -EPERM; - - dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n", - buf[i], reg + i, reg + i); - ret = regmap_write(wm831x->regmap, reg + i, buf[i]); - if (ret != 0) - return ret; - } - - return 0; -} - -/** - * wm831x_reg_write: Write a single WM831x register. - * - * @wm831x: Device to write to. - * @reg: Register to write to. - * @val: Value to write. - */ -int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg, - unsigned short val) -{ - int ret; - - mutex_lock(&wm831x->io_lock); - - ret = wm831x_write(wm831x, reg, 2, &val); - - mutex_unlock(&wm831x->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm831x_reg_write); - -/** - * wm831x_set_bits: Set the value of a bitfield in a WM831x register - * - * @wm831x: Device to write to. - * @reg: Register to write to. - * @mask: Mask of bits to set. - * @val: Value to set (unshifted) - */ -int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg, - unsigned short mask, unsigned short val) -{ - int ret; - - mutex_lock(&wm831x->io_lock); - - if (!wm831x_reg_locked(wm831x, reg)) - ret = regmap_update_bits(wm831x->regmap, reg, mask, val); - else - ret = -EPERM; - - mutex_unlock(&wm831x->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm831x_set_bits); - -static struct resource wm831x_dcdc1_resources[] = { - { - .start = WM831X_DC1_CONTROL_1, - .end = WM831X_DC1_DVS_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC1, - .end = WM831X_IRQ_UV_DC1, - .flags = IORESOURCE_IRQ, - }, - { - .name = "HC", - .start = WM831X_IRQ_HC_DC1, - .end = WM831X_IRQ_HC_DC1, - .flags = IORESOURCE_IRQ, - }, -}; - - -static struct resource wm831x_dcdc2_resources[] = { - { - .start = WM831X_DC2_CONTROL_1, - .end = WM831X_DC2_DVS_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC2, - .end = WM831X_IRQ_UV_DC2, - .flags = IORESOURCE_IRQ, - }, - { - .name = "HC", - .start = WM831X_IRQ_HC_DC2, - .end = WM831X_IRQ_HC_DC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_dcdc3_resources[] = { - { - .start = WM831X_DC3_CONTROL_1, - .end = WM831X_DC3_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC3, - .end = WM831X_IRQ_UV_DC3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_dcdc4_resources[] = { - { - .start = WM831X_DC4_CONTROL, - .end = WM831X_DC4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC4, - .end = WM831X_IRQ_UV_DC4, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm8320_dcdc4_buck_resources[] = { - { - .start = WM831X_DC4_CONTROL, - .end = WM832X_DC4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC4, - .end = WM831X_IRQ_UV_DC4, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_gpio_resources[] = { - { - .start = WM831X_IRQ_GPIO_1, - .end = WM831X_IRQ_GPIO_16, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_isink1_resources[] = { - { - .start = WM831X_CURRENT_SINK_1, - .end = WM831X_CURRENT_SINK_1, - .flags = IORESOURCE_IO, - }, - { - .start = WM831X_IRQ_CS1, - .end = WM831X_IRQ_CS1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_isink2_resources[] = { - { - .start = WM831X_CURRENT_SINK_2, - .end = WM831X_CURRENT_SINK_2, - .flags = IORESOURCE_IO, - }, - { - .start = WM831X_IRQ_CS2, - .end = WM831X_IRQ_CS2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo1_resources[] = { - { - .start = WM831X_LDO1_CONTROL, - .end = WM831X_LDO1_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO1, - .end = WM831X_IRQ_UV_LDO1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo2_resources[] = { - { - .start = WM831X_LDO2_CONTROL, - .end = WM831X_LDO2_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO2, - .end = WM831X_IRQ_UV_LDO2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo3_resources[] = { - { - .start = WM831X_LDO3_CONTROL, - .end = WM831X_LDO3_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO3, - .end = WM831X_IRQ_UV_LDO3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo4_resources[] = { - { - .start = WM831X_LDO4_CONTROL, - .end = WM831X_LDO4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO4, - .end = WM831X_IRQ_UV_LDO4, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo5_resources[] = { - { - .start = WM831X_LDO5_CONTROL, - .end = WM831X_LDO5_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO5, - .end = WM831X_IRQ_UV_LDO5, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo6_resources[] = { - { - .start = WM831X_LDO6_CONTROL, - .end = WM831X_LDO6_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO6, - .end = WM831X_IRQ_UV_LDO6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo7_resources[] = { - { - .start = WM831X_LDO7_CONTROL, - .end = WM831X_LDO7_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO7, - .end = WM831X_IRQ_UV_LDO7, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo8_resources[] = { - { - .start = WM831X_LDO8_CONTROL, - .end = WM831X_LDO8_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO8, - .end = WM831X_IRQ_UV_LDO8, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo9_resources[] = { - { - .start = WM831X_LDO9_CONTROL, - .end = WM831X_LDO9_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO9, - .end = WM831X_IRQ_UV_LDO9, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo10_resources[] = { - { - .start = WM831X_LDO10_CONTROL, - .end = WM831X_LDO10_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO10, - .end = WM831X_IRQ_UV_LDO10, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_ldo11_resources[] = { - { - .start = WM831X_LDO11_ON_CONTROL, - .end = WM831X_LDO11_SLEEP_CONTROL, - .flags = IORESOURCE_IO, - }, -}; - -static struct resource wm831x_on_resources[] = { - { - .start = WM831X_IRQ_ON, - .end = WM831X_IRQ_ON, - .flags = IORESOURCE_IRQ, - }, -}; - - -static struct resource wm831x_power_resources[] = { - { - .name = "SYSLO", - .start = WM831X_IRQ_PPM_SYSLO, - .end = WM831X_IRQ_PPM_SYSLO, - .flags = IORESOURCE_IRQ, - }, - { - .name = "PWR SRC", - .start = WM831X_IRQ_PPM_PWR_SRC, - .end = WM831X_IRQ_PPM_PWR_SRC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB CURR", - .start = WM831X_IRQ_PPM_USB_CURR, - .end = WM831X_IRQ_PPM_USB_CURR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT HOT", - .start = WM831X_IRQ_CHG_BATT_HOT, - .end = WM831X_IRQ_CHG_BATT_HOT, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT COLD", - .start = WM831X_IRQ_CHG_BATT_COLD, - .end = WM831X_IRQ_CHG_BATT_COLD, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT FAIL", - .start = WM831X_IRQ_CHG_BATT_FAIL, - .end = WM831X_IRQ_CHG_BATT_FAIL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "OV", - .start = WM831X_IRQ_CHG_OV, - .end = WM831X_IRQ_CHG_OV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "END", - .start = WM831X_IRQ_CHG_END, - .end = WM831X_IRQ_CHG_END, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TO", - .start = WM831X_IRQ_CHG_TO, - .end = WM831X_IRQ_CHG_TO, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MODE", - .start = WM831X_IRQ_CHG_MODE, - .end = WM831X_IRQ_CHG_MODE, - .flags = IORESOURCE_IRQ, - }, - { - .name = "START", - .start = WM831X_IRQ_CHG_START, - .end = WM831X_IRQ_CHG_START, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_rtc_resources[] = { - { - .name = "PER", - .start = WM831X_IRQ_RTC_PER, - .end = WM831X_IRQ_RTC_PER, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ALM", - .start = WM831X_IRQ_RTC_ALM, - .end = WM831X_IRQ_RTC_ALM, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_status1_resources[] = { - { - .start = WM831X_STATUS_LED_1, - .end = WM831X_STATUS_LED_1, - .flags = IORESOURCE_IO, - }, -}; - -static struct resource wm831x_status2_resources[] = { - { - .start = WM831X_STATUS_LED_2, - .end = WM831X_STATUS_LED_2, - .flags = IORESOURCE_IO, - }, -}; - -static struct resource wm831x_touch_resources[] = { - { - .name = "TCHPD", - .start = WM831X_IRQ_TCHPD, - .end = WM831X_IRQ_TCHPD, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TCHDATA", - .start = WM831X_IRQ_TCHDATA, - .end = WM831X_IRQ_TCHDATA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm831x_wdt_resources[] = { - { - .start = WM831X_IRQ_WDOG_TO, - .end = WM831X_IRQ_WDOG_TO, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell wm8310_devs[] = { - { - .name = "wm831x-backup", - }, - { - .name = "wm831x-buckv", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), - .resources = wm831x_dcdc1_resources, - }, - { - .name = "wm831x-buckv", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), - .resources = wm831x_dcdc2_resources, - }, - { - .name = "wm831x-buckp", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), - .resources = wm831x_dcdc3_resources, - }, - { - .name = "wm831x-boostp", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), - .resources = wm831x_dcdc4_resources, - }, - { - .name = "wm831x-clk", - }, - { - .name = "wm831x-epe", - .id = 1, - }, - { - .name = "wm831x-epe", - .id = 2, - }, - { - .name = "wm831x-gpio", - .num_resources = ARRAY_SIZE(wm831x_gpio_resources), - .resources = wm831x_gpio_resources, - }, - { - .name = "wm831x-hwmon", - }, - { - .name = "wm831x-isink", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_isink1_resources), - .resources = wm831x_isink1_resources, - }, - { - .name = "wm831x-isink", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_isink2_resources), - .resources = wm831x_isink2_resources, - }, - { - .name = "wm831x-ldo", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), - .resources = wm831x_ldo1_resources, - }, - { - .name = "wm831x-ldo", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), - .resources = wm831x_ldo2_resources, - }, - { - .name = "wm831x-ldo", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), - .resources = wm831x_ldo3_resources, - }, - { - .name = "wm831x-ldo", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), - .resources = wm831x_ldo4_resources, - }, - { - .name = "wm831x-ldo", - .id = 5, - .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), - .resources = wm831x_ldo5_resources, - }, - { - .name = "wm831x-ldo", - .id = 6, - .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), - .resources = wm831x_ldo6_resources, - }, - { - .name = "wm831x-aldo", - .id = 7, - .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), - .resources = wm831x_ldo7_resources, - }, - { - .name = "wm831x-aldo", - .id = 8, - .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), - .resources = wm831x_ldo8_resources, - }, - { - .name = "wm831x-aldo", - .id = 9, - .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), - .resources = wm831x_ldo9_resources, - }, - { - .name = "wm831x-aldo", - .id = 10, - .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), - .resources = wm831x_ldo10_resources, - }, - { - .name = "wm831x-alive-ldo", - .id = 11, - .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), - .resources = wm831x_ldo11_resources, - }, - { - .name = "wm831x-on", - .num_resources = ARRAY_SIZE(wm831x_on_resources), - .resources = wm831x_on_resources, - }, - { - .name = "wm831x-power", - .num_resources = ARRAY_SIZE(wm831x_power_resources), - .resources = wm831x_power_resources, - }, - { - .name = "wm831x-status", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_status1_resources), - .resources = wm831x_status1_resources, - }, - { - .name = "wm831x-status", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_status2_resources), - .resources = wm831x_status2_resources, - }, - { - .name = "wm831x-watchdog", - .num_resources = ARRAY_SIZE(wm831x_wdt_resources), - .resources = wm831x_wdt_resources, - }, -}; - -static struct mfd_cell wm8311_devs[] = { - { - .name = "wm831x-backup", - }, - { - .name = "wm831x-buckv", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), - .resources = wm831x_dcdc1_resources, - }, - { - .name = "wm831x-buckv", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), - .resources = wm831x_dcdc2_resources, - }, - { - .name = "wm831x-buckp", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), - .resources = wm831x_dcdc3_resources, - }, - { - .name = "wm831x-boostp", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), - .resources = wm831x_dcdc4_resources, - }, - { - .name = "wm831x-clk", - }, - { - .name = "wm831x-epe", - .id = 1, - }, - { - .name = "wm831x-epe", - .id = 2, - }, - { - .name = "wm831x-gpio", - .num_resources = ARRAY_SIZE(wm831x_gpio_resources), - .resources = wm831x_gpio_resources, - }, - { - .name = "wm831x-hwmon", - }, - { - .name = "wm831x-isink", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_isink1_resources), - .resources = wm831x_isink1_resources, - }, - { - .name = "wm831x-isink", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_isink2_resources), - .resources = wm831x_isink2_resources, - }, - { - .name = "wm831x-ldo", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), - .resources = wm831x_ldo1_resources, - }, - { - .name = "wm831x-ldo", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), - .resources = wm831x_ldo2_resources, - }, - { - .name = "wm831x-ldo", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), - .resources = wm831x_ldo3_resources, - }, - { - .name = "wm831x-ldo", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), - .resources = wm831x_ldo4_resources, - }, - { - .name = "wm831x-ldo", - .id = 5, - .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), - .resources = wm831x_ldo5_resources, - }, - { - .name = "wm831x-aldo", - .id = 7, - .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), - .resources = wm831x_ldo7_resources, - }, - { - .name = "wm831x-alive-ldo", - .id = 11, - .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), - .resources = wm831x_ldo11_resources, - }, - { - .name = "wm831x-on", - .num_resources = ARRAY_SIZE(wm831x_on_resources), - .resources = wm831x_on_resources, - }, - { - .name = "wm831x-power", - .num_resources = ARRAY_SIZE(wm831x_power_resources), - .resources = wm831x_power_resources, - }, - { - .name = "wm831x-status", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_status1_resources), - .resources = wm831x_status1_resources, - }, - { - .name = "wm831x-status", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_status2_resources), - .resources = wm831x_status2_resources, - }, - { - .name = "wm831x-watchdog", - .num_resources = ARRAY_SIZE(wm831x_wdt_resources), - .resources = wm831x_wdt_resources, - }, -}; - -static struct mfd_cell wm8312_devs[] = { - { - .name = "wm831x-backup", - }, - { - .name = "wm831x-buckv", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), - .resources = wm831x_dcdc1_resources, - }, - { - .name = "wm831x-buckv", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), - .resources = wm831x_dcdc2_resources, - }, - { - .name = "wm831x-buckp", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), - .resources = wm831x_dcdc3_resources, - }, - { - .name = "wm831x-boostp", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), - .resources = wm831x_dcdc4_resources, - }, - { - .name = "wm831x-clk", - }, - { - .name = "wm831x-epe", - .id = 1, - }, - { - .name = "wm831x-epe", - .id = 2, - }, - { - .name = "wm831x-gpio", - .num_resources = ARRAY_SIZE(wm831x_gpio_resources), - .resources = wm831x_gpio_resources, - }, - { - .name = "wm831x-hwmon", - }, - { - .name = "wm831x-isink", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_isink1_resources), - .resources = wm831x_isink1_resources, - }, - { - .name = "wm831x-isink", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_isink2_resources), - .resources = wm831x_isink2_resources, - }, - { - .name = "wm831x-ldo", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), - .resources = wm831x_ldo1_resources, - }, - { - .name = "wm831x-ldo", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), - .resources = wm831x_ldo2_resources, - }, - { - .name = "wm831x-ldo", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), - .resources = wm831x_ldo3_resources, - }, - { - .name = "wm831x-ldo", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), - .resources = wm831x_ldo4_resources, - }, - { - .name = "wm831x-ldo", - .id = 5, - .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), - .resources = wm831x_ldo5_resources, - }, - { - .name = "wm831x-ldo", - .id = 6, - .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), - .resources = wm831x_ldo6_resources, - }, - { - .name = "wm831x-aldo", - .id = 7, - .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), - .resources = wm831x_ldo7_resources, - }, - { - .name = "wm831x-aldo", - .id = 8, - .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), - .resources = wm831x_ldo8_resources, - }, - { - .name = "wm831x-aldo", - .id = 9, - .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), - .resources = wm831x_ldo9_resources, - }, - { - .name = "wm831x-aldo", - .id = 10, - .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), - .resources = wm831x_ldo10_resources, - }, - { - .name = "wm831x-alive-ldo", - .id = 11, - .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), - .resources = wm831x_ldo11_resources, - }, - { - .name = "wm831x-on", - .num_resources = ARRAY_SIZE(wm831x_on_resources), - .resources = wm831x_on_resources, - }, - { - .name = "wm831x-power", - .num_resources = ARRAY_SIZE(wm831x_power_resources), - .resources = wm831x_power_resources, - }, - { - .name = "wm831x-status", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_status1_resources), - .resources = wm831x_status1_resources, - }, - { - .name = "wm831x-status", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_status2_resources), - .resources = wm831x_status2_resources, - }, - { - .name = "wm831x-watchdog", - .num_resources = ARRAY_SIZE(wm831x_wdt_resources), - .resources = wm831x_wdt_resources, - }, -}; - -static struct mfd_cell wm8320_devs[] = { - { - .name = "wm831x-backup", - }, - { - .name = "wm831x-buckv", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), - .resources = wm831x_dcdc1_resources, - }, - { - .name = "wm831x-buckv", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), - .resources = wm831x_dcdc2_resources, - }, - { - .name = "wm831x-buckp", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), - .resources = wm831x_dcdc3_resources, - }, - { - .name = "wm831x-buckp", - .id = 4, - .num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources), - .resources = wm8320_dcdc4_buck_resources, - }, - { - .name = "wm831x-clk", - }, - { - .name = "wm831x-gpio", - .num_resources = ARRAY_SIZE(wm831x_gpio_resources), - .resources = wm831x_gpio_resources, - }, - { - .name = "wm831x-hwmon", - }, - { - .name = "wm831x-ldo", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), - .resources = wm831x_ldo1_resources, - }, - { - .name = "wm831x-ldo", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), - .resources = wm831x_ldo2_resources, - }, - { - .name = "wm831x-ldo", - .id = 3, - .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), - .resources = wm831x_ldo3_resources, - }, - { - .name = "wm831x-ldo", - .id = 4, - .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), - .resources = wm831x_ldo4_resources, - }, - { - .name = "wm831x-ldo", - .id = 5, - .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), - .resources = wm831x_ldo5_resources, - }, - { - .name = "wm831x-ldo", - .id = 6, - .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), - .resources = wm831x_ldo6_resources, - }, - { - .name = "wm831x-aldo", - .id = 7, - .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), - .resources = wm831x_ldo7_resources, - }, - { - .name = "wm831x-aldo", - .id = 8, - .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), - .resources = wm831x_ldo8_resources, - }, - { - .name = "wm831x-aldo", - .id = 9, - .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), - .resources = wm831x_ldo9_resources, - }, - { - .name = "wm831x-aldo", - .id = 10, - .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), - .resources = wm831x_ldo10_resources, - }, - { - .name = "wm831x-alive-ldo", - .id = 11, - .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), - .resources = wm831x_ldo11_resources, - }, - { - .name = "wm831x-on", - .num_resources = ARRAY_SIZE(wm831x_on_resources), - .resources = wm831x_on_resources, - }, - { - .name = "wm831x-status", - .id = 1, - .num_resources = ARRAY_SIZE(wm831x_status1_resources), - .resources = wm831x_status1_resources, - }, - { - .name = "wm831x-status", - .id = 2, - .num_resources = ARRAY_SIZE(wm831x_status2_resources), - .resources = wm831x_status2_resources, - }, - { - .name = "wm831x-watchdog", - .num_resources = ARRAY_SIZE(wm831x_wdt_resources), - .resources = wm831x_wdt_resources, - }, -}; - -static struct mfd_cell touch_devs[] = { - { - .name = "wm831x-touch", - .num_resources = ARRAY_SIZE(wm831x_touch_resources), - .resources = wm831x_touch_resources, - }, -}; - -static struct mfd_cell rtc_devs[] = { - { - .name = "wm831x-rtc", - .num_resources = ARRAY_SIZE(wm831x_rtc_resources), - .resources = wm831x_rtc_resources, - }, -}; - -static struct mfd_cell backlight_devs[] = { - { - .name = "wm831x-backlight", - }, -}; - -struct regmap_config wm831x_regmap_config = { - .reg_bits = 16, - .val_bits = 16, - - .cache_type = REGCACHE_RBTREE, - - .max_register = WM831X_DBE_CHECK_DATA, - .readable_reg = wm831x_reg_readable, - .writeable_reg = wm831x_reg_writeable, - .volatile_reg = wm831x_reg_volatile, -}; -EXPORT_SYMBOL_GPL(wm831x_regmap_config); - -/* - * Instantiate the generic non-control parts of the device. - */ -int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) -{ - struct wm831x_pdata *pdata = wm831x->dev->platform_data; - int rev, wm831x_num; - enum wm831x_parent parent; - int ret, i; - - mutex_init(&wm831x->io_lock); - mutex_init(&wm831x->key_lock); - dev_set_drvdata(wm831x->dev, wm831x); - wm831x->soft_shutdown = pdata->soft_shutdown; - - ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); - goto err; - } - switch (ret) { - case 0x6204: - case 0x6246: - break; - default: - dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); - ret = -EINVAL; - goto err; - } - - ret = wm831x_reg_read(wm831x, WM831X_REVISION); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read revision: %d\n", ret); - goto err; - } - rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT; - - ret = wm831x_reg_read(wm831x, WM831X_RESET_ID); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret); - goto err; - } - - /* Some engineering samples do not have the ID set, rely on - * the device being registered correctly. - */ - if (ret == 0) { - dev_info(wm831x->dev, "Device is an engineering sample\n"); - ret = id; - } - - switch (ret) { - case WM8310: - parent = WM8310; - wm831x->num_gpio = 16; - wm831x->charger_irq_wake = 1; - if (rev > 0) { - wm831x->has_gpio_ena = 1; - wm831x->has_cs_sts = 1; - } - - dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev); - break; - - case WM8311: - parent = WM8311; - wm831x->num_gpio = 16; - wm831x->charger_irq_wake = 1; - if (rev > 0) { - wm831x->has_gpio_ena = 1; - wm831x->has_cs_sts = 1; - } - - dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev); - break; - - case WM8312: - parent = WM8312; - wm831x->num_gpio = 16; - wm831x->charger_irq_wake = 1; - if (rev > 0) { - wm831x->has_gpio_ena = 1; - wm831x->has_cs_sts = 1; - } - - dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev); - break; - - case WM8320: - parent = WM8320; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev); - break; - - case WM8321: - parent = WM8321; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev); - break; - - case WM8325: - parent = WM8325; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); - break; - - case WM8326: - parent = WM8326; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev); - break; - - default: - dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); - ret = -EINVAL; - goto err; - } - - /* This will need revisiting in future but is OK for all - * current parts. - */ - if (parent != id) - dev_warn(wm831x->dev, "Device was registered as a WM%lx\n", - id); - - /* Bootstrap the user key */ - ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read security key: %d\n", ret); - goto err; - } - if (ret != 0) { - dev_warn(wm831x->dev, "Security key had non-zero value %x\n", - ret); - wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0); - } - wm831x->locked = 1; - - if (pdata && pdata->pre_init) { - ret = pdata->pre_init(wm831x); - if (ret != 0) { - dev_err(wm831x->dev, "pre_init() failed: %d\n", ret); - goto err; - } - } - - if (pdata) { - for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { - if (!pdata->gpio_defaults[i]) - continue; - - wm831x_reg_write(wm831x, - WM831X_GPIO1_CONTROL + i, - pdata->gpio_defaults[i] & 0xffff); - } - } - - /* Multiply by 10 as we have many subdevices of the same type */ - if (pdata && pdata->wm831x_num) - wm831x_num = pdata->wm831x_num * 10; - else - wm831x_num = -1; - - ret = wm831x_irq_init(wm831x, irq); - if (ret != 0) - goto err; - - wm831x_auxadc_init(wm831x); - - /* The core device is up, instantiate the subdevices. */ - switch (parent) { - case WM8310: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8310_devs, ARRAY_SIZE(wm8310_devs), - NULL, wm831x->irq_base); - break; - - case WM8311: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8311_devs, ARRAY_SIZE(wm8311_devs), - NULL, wm831x->irq_base); - if (!pdata || !pdata->disable_touch) - mfd_add_devices(wm831x->dev, wm831x_num, - touch_devs, ARRAY_SIZE(touch_devs), - NULL, wm831x->irq_base); - break; - - case WM8312: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8312_devs, ARRAY_SIZE(wm8312_devs), - NULL, wm831x->irq_base); - if (!pdata || !pdata->disable_touch) - mfd_add_devices(wm831x->dev, wm831x_num, - touch_devs, ARRAY_SIZE(touch_devs), - NULL, wm831x->irq_base); - break; - - case WM8320: - case WM8321: - case WM8325: - case WM8326: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, wm831x->irq_base); - break; - - default: - /* If this happens the bus probe function is buggy */ - BUG(); - } - - if (ret != 0) { - dev_err(wm831x->dev, "Failed to add children\n"); - goto err_irq; - } - - /* The RTC can only be used if the 32.768kHz crystal is - * enabled; this can't be controlled by software at runtime. - */ - ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret); - goto err_irq; - } - - if (ret & WM831X_XTAL_ENA) { - ret = mfd_add_devices(wm831x->dev, wm831x_num, - rtc_devs, ARRAY_SIZE(rtc_devs), - NULL, wm831x->irq_base); - if (ret != 0) { - dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); - goto err_irq; - } - } else { - dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n"); - } - - if (pdata && pdata->backlight) { - /* Treat errors as non-critical */ - ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, - ARRAY_SIZE(backlight_devs), NULL, - wm831x->irq_base); - if (ret < 0) - dev_err(wm831x->dev, "Failed to add backlight: %d\n", - ret); - } - - wm831x_otp_init(wm831x); - - if (pdata && pdata->post_init) { - ret = pdata->post_init(wm831x); - if (ret != 0) { - dev_err(wm831x->dev, "post_init() failed: %d\n", ret); - goto err_irq; - } - } - - return 0; - -err_irq: - wm831x_irq_exit(wm831x); -err: - mfd_remove_devices(wm831x->dev); - return ret; -} - -void wm831x_device_exit(struct wm831x *wm831x) -{ - wm831x_otp_exit(wm831x); - mfd_remove_devices(wm831x->dev); - if (wm831x->irq_base) - free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); - wm831x_irq_exit(wm831x); -} - -int wm831x_device_suspend(struct wm831x *wm831x) -{ - int reg, mask; - - /* If the charger IRQs are a wake source then make sure we ack - * them even if they're not actively being used (eg, no power - * driver or no IRQ line wired up) then acknowledge the - * interrupts otherwise suspend won't last very long. - */ - if (wm831x->charger_irq_wake) { - reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK); - - mask = WM831X_CHG_BATT_HOT_EINT | - WM831X_CHG_BATT_COLD_EINT | - WM831X_CHG_BATT_FAIL_EINT | - WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT | - WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT | - WM831X_CHG_START_EINT; - - /* If any of the interrupts are masked read the statuses */ - if (reg & mask) - reg = wm831x_reg_read(wm831x, - WM831X_INTERRUPT_STATUS_2); - - if (reg & mask) { - dev_info(wm831x->dev, - "Acknowledging masked charger IRQs: %x\n", - reg & mask); - wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2, - reg & mask); - } - } - - return 0; -} - -void wm831x_device_shutdown(struct wm831x *wm831x) -{ - if (wm831x->soft_shutdown) { - dev_info(wm831x->dev, "Initiating shutdown...\n"); - wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0); - } -} -EXPORT_SYMBOL_GPL(wm831x_device_shutdown); - -MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-i2c.c b/ANDROID_3.4.5/drivers/mfd/wm831x-i2c.c deleted file mode 100644 index 2b29caeb..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-i2c.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * wm831x-i2c.c -- I2C access for Wolfson WM831x PMICs - * - * Copyright 2009,2010 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/mfd/core.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/regmap.h> - -#include <linux/mfd/wm831x/core.h> -#include <linux/mfd/wm831x/pdata.h> - -static int wm831x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm831x *wm831x; - int ret; - - wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL); - if (wm831x == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm831x); - wm831x->dev = &i2c->dev; - - wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config); - if (IS_ERR(wm831x->regmap)) { - ret = PTR_ERR(wm831x->regmap); - dev_err(wm831x->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - return wm831x_device_init(wm831x, id->driver_data, i2c->irq); -} - -static int wm831x_i2c_remove(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - - wm831x_device_exit(wm831x); - - return 0; -} - -static int wm831x_i2c_suspend(struct device *dev) -{ - struct wm831x *wm831x = dev_get_drvdata(dev); - - return wm831x_device_suspend(wm831x); -} - -static void wm831x_i2c_shutdown(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - - wm831x_device_shutdown(wm831x); -} - -static const struct i2c_device_id wm831x_i2c_id[] = { - { "wm8310", WM8310 }, - { "wm8311", WM8311 }, - { "wm8312", WM8312 }, - { "wm8320", WM8320 }, - { "wm8321", WM8321 }, - { "wm8325", WM8325 }, - { "wm8326", WM8326 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); - -static const struct dev_pm_ops wm831x_pm_ops = { - .suspend = wm831x_i2c_suspend, -}; - -static struct i2c_driver wm831x_i2c_driver = { - .driver = { - .name = "wm831x", - .owner = THIS_MODULE, - .pm = &wm831x_pm_ops, - }, - .probe = wm831x_i2c_probe, - .remove = wm831x_i2c_remove, - .shutdown = wm831x_i2c_shutdown, - .id_table = wm831x_i2c_id, -}; - -static int __init wm831x_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&wm831x_i2c_driver); - if (ret != 0) - pr_err("Failed to register wm831x I2C driver: %d\n", ret); - - return ret; -} -subsys_initcall(wm831x_i2c_init); - -static void __exit wm831x_i2c_exit(void) -{ - i2c_del_driver(&wm831x_i2c_driver); -} -module_exit(wm831x_i2c_exit); diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-irq.c b/ANDROID_3.4.5/drivers/mfd/wm831x-irq.c deleted file mode 100644 index bec4d053..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-irq.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - * wm831x-irq.c -- Interrupt controller support for Wolfson WM831x PMICs - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/mfd/core.h> -#include <linux/interrupt.h> - -#include <linux/mfd/wm831x/core.h> -#include <linux/mfd/wm831x/pdata.h> -#include <linux/mfd/wm831x/gpio.h> -#include <linux/mfd/wm831x/irq.h> - -#include <linux/delay.h> - -struct wm831x_irq_data { - int primary; - int reg; - int mask; -}; - -static struct wm831x_irq_data wm831x_irqs[] = { - [WM831X_IRQ_TEMP_THW] = { - .primary = WM831X_TEMP_INT, - .reg = 1, - .mask = WM831X_TEMP_THW_EINT, - }, - [WM831X_IRQ_GPIO_1] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP1_EINT, - }, - [WM831X_IRQ_GPIO_2] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP2_EINT, - }, - [WM831X_IRQ_GPIO_3] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP3_EINT, - }, - [WM831X_IRQ_GPIO_4] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP4_EINT, - }, - [WM831X_IRQ_GPIO_5] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP5_EINT, - }, - [WM831X_IRQ_GPIO_6] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP6_EINT, - }, - [WM831X_IRQ_GPIO_7] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP7_EINT, - }, - [WM831X_IRQ_GPIO_8] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP8_EINT, - }, - [WM831X_IRQ_GPIO_9] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP9_EINT, - }, - [WM831X_IRQ_GPIO_10] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP10_EINT, - }, - [WM831X_IRQ_GPIO_11] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP11_EINT, - }, - [WM831X_IRQ_GPIO_12] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP12_EINT, - }, - [WM831X_IRQ_GPIO_13] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP13_EINT, - }, - [WM831X_IRQ_GPIO_14] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP14_EINT, - }, - [WM831X_IRQ_GPIO_15] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP15_EINT, - }, - [WM831X_IRQ_GPIO_16] = { - .primary = WM831X_GP_INT, - .reg = 5, - .mask = WM831X_GP16_EINT, - }, - [WM831X_IRQ_ON] = { - .primary = WM831X_ON_PIN_INT, - .reg = 1, - .mask = WM831X_ON_PIN_EINT, - }, - [WM831X_IRQ_PPM_SYSLO] = { - .primary = WM831X_PPM_INT, - .reg = 1, - .mask = WM831X_PPM_SYSLO_EINT, - }, - [WM831X_IRQ_PPM_PWR_SRC] = { - .primary = WM831X_PPM_INT, - .reg = 1, - .mask = WM831X_PPM_PWR_SRC_EINT, - }, - [WM831X_IRQ_PPM_USB_CURR] = { - .primary = WM831X_PPM_INT, - .reg = 1, - .mask = WM831X_PPM_USB_CURR_EINT, - }, - [WM831X_IRQ_WDOG_TO] = { - .primary = WM831X_WDOG_INT, - .reg = 1, - .mask = WM831X_WDOG_TO_EINT, - }, - [WM831X_IRQ_RTC_PER] = { - .primary = WM831X_RTC_INT, - .reg = 1, - .mask = WM831X_RTC_PER_EINT, - }, - [WM831X_IRQ_RTC_ALM] = { - .primary = WM831X_RTC_INT, - .reg = 1, - .mask = WM831X_RTC_ALM_EINT, - }, - [WM831X_IRQ_CHG_BATT_HOT] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_BATT_HOT_EINT, - }, - [WM831X_IRQ_CHG_BATT_COLD] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_BATT_COLD_EINT, - }, - [WM831X_IRQ_CHG_BATT_FAIL] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_BATT_FAIL_EINT, - }, - [WM831X_IRQ_CHG_OV] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_OV_EINT, - }, - [WM831X_IRQ_CHG_END] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_END_EINT, - }, - [WM831X_IRQ_CHG_TO] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_TO_EINT, - }, - [WM831X_IRQ_CHG_MODE] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_MODE_EINT, - }, - [WM831X_IRQ_CHG_START] = { - .primary = WM831X_CHG_INT, - .reg = 2, - .mask = WM831X_CHG_START_EINT, - }, - [WM831X_IRQ_TCHDATA] = { - .primary = WM831X_TCHDATA_INT, - .reg = 1, - .mask = WM831X_TCHDATA_EINT, - }, - [WM831X_IRQ_TCHPD] = { - .primary = WM831X_TCHPD_INT, - .reg = 1, - .mask = WM831X_TCHPD_EINT, - }, - [WM831X_IRQ_AUXADC_DATA] = { - .primary = WM831X_AUXADC_INT, - .reg = 1, - .mask = WM831X_AUXADC_DATA_EINT, - }, - [WM831X_IRQ_AUXADC_DCOMP1] = { - .primary = WM831X_AUXADC_INT, - .reg = 1, - .mask = WM831X_AUXADC_DCOMP1_EINT, - }, - [WM831X_IRQ_AUXADC_DCOMP2] = { - .primary = WM831X_AUXADC_INT, - .reg = 1, - .mask = WM831X_AUXADC_DCOMP2_EINT, - }, - [WM831X_IRQ_AUXADC_DCOMP3] = { - .primary = WM831X_AUXADC_INT, - .reg = 1, - .mask = WM831X_AUXADC_DCOMP3_EINT, - }, - [WM831X_IRQ_AUXADC_DCOMP4] = { - .primary = WM831X_AUXADC_INT, - .reg = 1, - .mask = WM831X_AUXADC_DCOMP4_EINT, - }, - [WM831X_IRQ_CS1] = { - .primary = WM831X_CS_INT, - .reg = 2, - .mask = WM831X_CS1_EINT, - }, - [WM831X_IRQ_CS2] = { - .primary = WM831X_CS_INT, - .reg = 2, - .mask = WM831X_CS2_EINT, - }, - [WM831X_IRQ_HC_DC1] = { - .primary = WM831X_HC_INT, - .reg = 4, - .mask = WM831X_HC_DC1_EINT, - }, - [WM831X_IRQ_HC_DC2] = { - .primary = WM831X_HC_INT, - .reg = 4, - .mask = WM831X_HC_DC2_EINT, - }, - [WM831X_IRQ_UV_LDO1] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO1_EINT, - }, - [WM831X_IRQ_UV_LDO2] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO2_EINT, - }, - [WM831X_IRQ_UV_LDO3] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO3_EINT, - }, - [WM831X_IRQ_UV_LDO4] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO4_EINT, - }, - [WM831X_IRQ_UV_LDO5] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO5_EINT, - }, - [WM831X_IRQ_UV_LDO6] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO6_EINT, - }, - [WM831X_IRQ_UV_LDO7] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO7_EINT, - }, - [WM831X_IRQ_UV_LDO8] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO8_EINT, - }, - [WM831X_IRQ_UV_LDO9] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO9_EINT, - }, - [WM831X_IRQ_UV_LDO10] = { - .primary = WM831X_UV_INT, - .reg = 3, - .mask = WM831X_UV_LDO10_EINT, - }, - [WM831X_IRQ_UV_DC1] = { - .primary = WM831X_UV_INT, - .reg = 4, - .mask = WM831X_UV_DC1_EINT, - }, - [WM831X_IRQ_UV_DC2] = { - .primary = WM831X_UV_INT, - .reg = 4, - .mask = WM831X_UV_DC2_EINT, - }, - [WM831X_IRQ_UV_DC3] = { - .primary = WM831X_UV_INT, - .reg = 4, - .mask = WM831X_UV_DC3_EINT, - }, - [WM831X_IRQ_UV_DC4] = { - .primary = WM831X_UV_INT, - .reg = 4, - .mask = WM831X_UV_DC4_EINT, - }, -}; - -static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data) -{ - return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg; -} - -static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, - int irq) -{ - return &wm831x_irqs[irq - wm831x->irq_base]; -} - -static void wm831x_irq_lock(struct irq_data *data) -{ - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - - mutex_lock(&wm831x->irq_lock); -} - -static void wm831x_irq_sync_unlock(struct irq_data *data) -{ - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) { - if (wm831x->gpio_update[i]) { - wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i, - WM831X_GPN_INT_MODE | WM831X_GPN_POL, - wm831x->gpio_update[i]); - wm831x->gpio_update[i] = 0; - } - } - - for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { - /* If there's been a change in the mask write it back - * to the hardware. */ - if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { - dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n", - WM831X_INTERRUPT_STATUS_1_MASK + i, - wm831x->irq_masks_cur[i]); - - wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; - wm831x_reg_write(wm831x, - WM831X_INTERRUPT_STATUS_1_MASK + i, - wm831x->irq_masks_cur[i]); - } - } - - mutex_unlock(&wm831x->irq_lock); -} - -static void wm831x_irq_enable(struct irq_data *data) -{ - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, - data->irq); - - wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; -} - -static void wm831x_irq_disable(struct irq_data *data) -{ - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, - data->irq); - - wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; -} - -static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) -{ - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - int irq; - - irq = data->irq - wm831x->irq_base; - - if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { - /* Ignore internal-only IRQs */ - if (irq >= 0 && irq < WM831X_NUM_IRQS) - return 0; - else - return -EINVAL; - } - - /* Rebase the IRQ into the GPIO range so we've got a sensible array - * index. - */ - irq -= WM831X_IRQ_GPIO_1; - - /* We set the high bit to flag that we need an update; don't - * do the update here as we can be called with the bus lock - * held. - */ - switch (type) { - case IRQ_TYPE_EDGE_BOTH: - wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; - wm831x->gpio_level[irq] = false; - break; - case IRQ_TYPE_EDGE_RISING: - wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; - wm831x->gpio_level[irq] = false; - break; - case IRQ_TYPE_EDGE_FALLING: - 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; - default: - return -EINVAL; - } - - return 0; -} - -static struct irq_chip wm831x_irq_chip = { - .name = "wm831x", - .irq_bus_lock = wm831x_irq_lock, - .irq_bus_sync_unlock = wm831x_irq_sync_unlock, - .irq_disable = wm831x_irq_disable, - .irq_enable = wm831x_irq_enable, - .irq_set_type = wm831x_irq_set_type, -}; - -/* The processing of the primary interrupt occurs in a thread so that - * we can interact with the device over I2C or SPI. */ -static irqreturn_t wm831x_irq_thread(int irq, void *data) -{ - struct wm831x *wm831x = data; - unsigned int i; - int primary, status_addr, ret; - int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; - int read[WM831X_NUM_IRQ_REGS] = { 0 }; - int *status; - - primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS); - if (primary < 0) { - dev_err(wm831x->dev, "Failed to read system interrupt: %d\n", - primary); - goto out; - } - - /* The touch interrupts are visible in the primary register as - * an optimisation; open code this to avoid complicating the - * main handling loop and so we can also skip iterating the - * descriptors. - */ - if (primary & WM831X_TCHPD_INT) - handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); - if (primary & WM831X_TCHDATA_INT) - handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); - primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); - - for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { - int offset = wm831x_irqs[i].reg - 1; - - if (!(primary & wm831x_irqs[i].primary)) - continue; - - status = &status_regs[offset]; - - /* Hopefully there should only be one register to read - * each time otherwise we ought to do a block read. */ - if (!read[offset]) { - status_addr = irq_data_to_status_reg(&wm831x_irqs[i]); - - *status = wm831x_reg_read(wm831x, status_addr); - if (*status < 0) { - dev_err(wm831x->dev, - "Failed to read IRQ status: %d\n", - *status); - goto out; - } - - read[offset] = 1; - - /* Ignore any bits that we don't think are masked */ - *status &= ~wm831x->irq_masks_cur[offset]; - - /* Acknowledge now so we don't miss - * notifications while we handle. - */ - wm831x_reg_write(wm831x, status_addr, *status); - } - - if (*status & wm831x_irqs[i].mask) - 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: - return IRQ_HANDLED; -} - -int wm831x_irq_init(struct wm831x *wm831x, int irq) -{ - struct wm831x_pdata *pdata = wm831x->dev->platform_data; - int i, cur_irq, ret; - - mutex_init(&wm831x->irq_lock); - - /* Mask the individual interrupt sources */ - for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { - wm831x->irq_masks_cur[i] = 0xffff; - wm831x->irq_masks_cache[i] = 0xffff; - wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i, - 0xffff); - } - - /* Try to dynamically allocate IRQs if no base is specified */ - if (!pdata || !pdata->irq_base) - wm831x->irq_base = -1; - else - wm831x->irq_base = pdata->irq_base; - - wm831x->irq_base = irq_alloc_descs(wm831x->irq_base, 0, - WM831X_NUM_IRQS, 0); - if (wm831x->irq_base < 0) { - dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n", - wm831x->irq_base); - wm831x->irq_base = 0; - return 0; - } - - if (pdata && pdata->irq_cmos) - i = 0; - else - i = WM831X_IRQ_OD; - - wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, - WM831X_IRQ_OD, i); - - /* Try to flag /IRQ as a wake source; there are a number of - * unconditional wake sources in the PMIC so this isn't - * conditional but we don't actually care *too* much if it - * fails. - */ - ret = enable_irq_wake(irq); - if (ret != 0) { - dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n", - ret); - } - - wm831x->irq = irq; - - /* Register them with genirq */ - for (cur_irq = wm831x->irq_base; - cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; - cur_irq++) { - irq_set_chip_data(cur_irq, wm831x); - irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); - - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - if (irq) { - ret = request_threaded_irq(irq, NULL, wm831x_irq_thread, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "wm831x", wm831x); - if (ret != 0) { - dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n", - irq, ret); - return ret; - } - } else { - dev_warn(wm831x->dev, - "No interrupt specified - functionality limited\n"); - } - - /* Enable top level interrupts, we mask at secondary level */ - wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0); - - return 0; -} - -void wm831x_irq_exit(struct wm831x *wm831x) -{ - if (wm831x->irq) - free_irq(wm831x->irq, wm831x); -} diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-otp.c b/ANDROID_3.4.5/drivers/mfd/wm831x-otp.c deleted file mode 100644 index f742745f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-otp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * wm831x-otp.c -- OTP for Wolfson WM831x PMICs - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/bcd.h> -#include <linux/delay.h> -#include <linux/mfd/core.h> - -#include <linux/mfd/wm831x/core.h> -#include <linux/mfd/wm831x/otp.h> - -/* In bytes */ -#define WM831X_UNIQUE_ID_LEN 16 - -/* Read the unique ID from the chip into id */ -static int wm831x_unique_id_read(struct wm831x *wm831x, char *id) -{ - int i, val; - - for (i = 0; i < WM831X_UNIQUE_ID_LEN / 2; i++) { - val = wm831x_reg_read(wm831x, WM831X_UNIQUE_ID_1 + i); - if (val < 0) - return val; - - id[i * 2] = (val >> 8) & 0xff; - id[(i * 2) + 1] = val & 0xff; - } - - return 0; -} - -static ssize_t wm831x_unique_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct wm831x *wm831x = dev_get_drvdata(dev); - int i, rval; - char id[WM831X_UNIQUE_ID_LEN]; - ssize_t ret = 0; - - rval = wm831x_unique_id_read(wm831x, id); - if (rval < 0) - return 0; - - for (i = 0; i < WM831X_UNIQUE_ID_LEN; i++) - ret += sprintf(&buf[ret], "%02x", buf[i]); - - ret += sprintf(&buf[ret], "\n"); - - return ret; -} - -static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); - -int wm831x_otp_init(struct wm831x *wm831x) -{ - int ret; - - ret = device_create_file(wm831x->dev, &dev_attr_unique_id); - if (ret != 0) - dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", - ret); - - return ret; -} - -void wm831x_otp_exit(struct wm831x *wm831x) -{ - device_remove_file(wm831x->dev, &dev_attr_unique_id); -} - diff --git a/ANDROID_3.4.5/drivers/mfd/wm831x-spi.c b/ANDROID_3.4.5/drivers/mfd/wm831x-spi.c deleted file mode 100644 index 4bceee98..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm831x-spi.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * wm831x-spi.c -- SPI access for Wolfson WM831x PMICs - * - * Copyright 2009,2010 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pm.h> -#include <linux/spi/spi.h> -#include <linux/regmap.h> -#include <linux/err.h> - -#include <linux/mfd/wm831x/core.h> - -static int __devinit wm831x_spi_probe(struct spi_device *spi) -{ - const struct spi_device_id *id = spi_get_device_id(spi); - struct wm831x *wm831x; - enum wm831x_parent type; - int ret; - - type = (enum wm831x_parent)id->driver_data; - - wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL); - if (wm831x == NULL) - return -ENOMEM; - - spi->bits_per_word = 16; - spi->mode = SPI_MODE_0; - - dev_set_drvdata(&spi->dev, wm831x); - wm831x->dev = &spi->dev; - - wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config); - if (IS_ERR(wm831x->regmap)) { - ret = PTR_ERR(wm831x->regmap); - dev_err(wm831x->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - return wm831x_device_init(wm831x, type, spi->irq); -} - -static int __devexit wm831x_spi_remove(struct spi_device *spi) -{ - struct wm831x *wm831x = dev_get_drvdata(&spi->dev); - - wm831x_device_exit(wm831x); - - return 0; -} - -static int wm831x_spi_suspend(struct device *dev) -{ - struct wm831x *wm831x = dev_get_drvdata(dev); - - return wm831x_device_suspend(wm831x); -} - -static void wm831x_spi_shutdown(struct spi_device *spi) -{ - struct wm831x *wm831x = dev_get_drvdata(&spi->dev); - - wm831x_device_shutdown(wm831x); -} - -static const struct dev_pm_ops wm831x_spi_pm = { - .freeze = wm831x_spi_suspend, - .suspend = wm831x_spi_suspend, -}; - -static const struct spi_device_id wm831x_spi_ids[] = { - { "wm8310", WM8310 }, - { "wm8311", WM8311 }, - { "wm8312", WM8312 }, - { "wm8320", WM8320 }, - { "wm8321", WM8321 }, - { "wm8325", WM8325 }, - { "wm8326", WM8326 }, - { }, -}; -MODULE_DEVICE_TABLE(spi, wm831x_spi_ids); - -static struct spi_driver wm831x_spi_driver = { - .driver = { - .name = "wm831x", - .owner = THIS_MODULE, - .pm = &wm831x_spi_pm, - }, - .id_table = wm831x_spi_ids, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .shutdown = wm831x_spi_shutdown, -}; - -static int __init wm831x_spi_init(void) -{ - int ret; - - ret = spi_register_driver(&wm831x_spi_driver); - if (ret != 0) - pr_err("Failed to register WM831x SPI driver: %d\n", ret); - - return 0; -} -subsys_initcall(wm831x_spi_init); - -static void __exit wm831x_spi_exit(void) -{ - spi_unregister_driver(&wm831x_spi_driver); -} -module_exit(wm831x_spi_exit); - -MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8350-core.c b/ANDROID_3.4.5/drivers/mfd/wm8350-core.c deleted file mode 100644 index dd1caaac..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8350-core.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * wm8350-core.c -- Device access for Wolfson WM8350 - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood, Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/bug.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/workqueue.h> - -#include <linux/mfd/wm8350/core.h> -#include <linux/mfd/wm8350/audio.h> -#include <linux/mfd/wm8350/comparator.h> -#include <linux/mfd/wm8350/gpio.h> -#include <linux/mfd/wm8350/pmic.h> -#include <linux/mfd/wm8350/rtc.h> -#include <linux/mfd/wm8350/supply.h> -#include <linux/mfd/wm8350/wdt.h> - -#define WM8350_UNLOCK_KEY 0x0013 -#define WM8350_LOCK_KEY 0x0000 - -#define WM8350_CLOCK_CONTROL_1 0x28 -#define WM8350_AIF_TEST 0x74 - -/* debug */ -#define WM8350_BUS_DEBUG 0 -#if WM8350_BUS_DEBUG -#define dump(regs, src) do { \ - int i_; \ - u16 *src_ = src; \ - printk(KERN_DEBUG); \ - for (i_ = 0; i_ < regs; i_++) \ - printk(" 0x%4.4x", *src_++); \ - printk("\n"); \ -} while (0); -#else -#define dump(bytes, src) -#endif - -#define WM8350_LOCK_DEBUG 0 -#if WM8350_LOCK_DEBUG -#define ldbg(format, arg...) printk(format, ## arg) -#else -#define ldbg(format, arg...) -#endif - -/* - * WM8350 Device IO - */ -static DEFINE_MUTEX(io_mutex); -static DEFINE_MUTEX(reg_lock_mutex); - -/* Perform a physical read from the device. - */ -static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs, - u16 *dest) -{ - int i, ret; - int bytes = num_regs * 2; - - dev_dbg(wm8350->dev, "volatile read\n"); - ret = wm8350->read_dev(wm8350, reg, bytes, (char *)dest); - - for (i = reg; i < reg + num_regs; i++) { - /* Cache is CPU endian */ - dest[i - reg] = be16_to_cpu(dest[i - reg]); - - /* Mask out non-readable bits */ - dest[i - reg] &= wm8350_reg_io_map[i].readable; - } - - dump(num_regs, dest); - - return ret; -} - -static int wm8350_read(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *dest) -{ - int i; - int end = reg + num_regs; - int ret = 0; - int bytes = num_regs * 2; - - if (wm8350->read_dev == NULL) - return -ENODEV; - - if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { - dev_err(wm8350->dev, "invalid reg %x\n", - reg + num_regs - 1); - return -EINVAL; - } - - dev_dbg(wm8350->dev, - "%s R%d(0x%2.2x) %d regs\n", __func__, reg, reg, num_regs); - -#if WM8350_BUS_DEBUG - /* we can _safely_ read any register, but warn if read not supported */ - for (i = reg; i < end; i++) { - if (!wm8350_reg_io_map[i].readable) - dev_warn(wm8350->dev, - "reg R%d is not readable\n", i); - } -#endif - - /* if any volatile registers are required, then read back all */ - for (i = reg; i < end; i++) - if (wm8350_reg_io_map[i].vol) - return wm8350_phys_read(wm8350, reg, num_regs, dest); - - /* no volatiles, then cache is good */ - dev_dbg(wm8350->dev, "cache read\n"); - memcpy(dest, &wm8350->reg_cache[reg], bytes); - dump(num_regs, dest); - return ret; -} - -static inline int is_reg_locked(struct wm8350 *wm8350, u8 reg) -{ - if (reg == WM8350_SECURITY || - wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY) - return 0; - - if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 && - reg <= WM8350_GPIO_FUNCTION_SELECT_4) || - (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 && - reg <= WM8350_BATTERY_CHARGER_CONTROL_3)) - return 1; - return 0; -} - -static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) -{ - int i; - int end = reg + num_regs; - int bytes = num_regs * 2; - - if (wm8350->write_dev == NULL) - return -ENODEV; - - if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { - dev_err(wm8350->dev, "invalid reg %x\n", - reg + num_regs - 1); - return -EINVAL; - } - - /* it's generally not a good idea to write to RO or locked registers */ - for (i = reg; i < end; i++) { - if (!wm8350_reg_io_map[i].writable) { - dev_err(wm8350->dev, - "attempted write to read only reg R%d\n", i); - return -EINVAL; - } - - if (is_reg_locked(wm8350, i)) { - dev_err(wm8350->dev, - "attempted write to locked reg R%d\n", i); - return -EINVAL; - } - - src[i - reg] &= wm8350_reg_io_map[i].writable; - - wm8350->reg_cache[i] = - (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable) - | src[i - reg]; - - src[i - reg] = cpu_to_be16(src[i - reg]); - } - - /* Actually write it out */ - return wm8350->write_dev(wm8350, reg, bytes, (char *)src); -} - -/* - * Safe read, modify, write methods - */ -int wm8350_clear_bits(struct wm8350 *wm8350, u16 reg, u16 mask) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) { - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - goto out; - } - - data &= ~mask; - err = wm8350_write(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); -out: - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_clear_bits); - -int wm8350_set_bits(struct wm8350 *wm8350, u16 reg, u16 mask) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) { - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - goto out; - } - - data |= mask; - err = wm8350_write(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); -out: - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_set_bits); - -u16 wm8350_reg_read(struct wm8350 *wm8350, int reg) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - - mutex_unlock(&io_mutex); - return data; -} -EXPORT_SYMBOL_GPL(wm8350_reg_read); - -int wm8350_reg_write(struct wm8350 *wm8350, int reg, u16 val) -{ - int ret; - u16 data = val; - - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, reg, 1, &data); - if (ret) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_write); - -int wm8350_block_read(struct wm8350 *wm8350, int start_reg, int regs, - u16 *dest) -{ - int err = 0; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, start_reg, regs, dest); - if (err) - dev_err(wm8350->dev, "block read starting from R%d failed\n", - start_reg); - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_block_read); - -int wm8350_block_write(struct wm8350 *wm8350, int start_reg, int regs, - u16 *src) -{ - int ret = 0; - - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, start_reg, regs, src); - if (ret) - dev_err(wm8350->dev, "block write starting at R%d failed\n", - start_reg); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_block_write); - -/** - * wm8350_reg_lock() - * - * The WM8350 has a hardware lock which can be used to prevent writes to - * some registers (generally those which can cause particularly serious - * problems if misused). This function enables that lock. - */ -int wm8350_reg_lock(struct wm8350 *wm8350) -{ - u16 key = WM8350_LOCK_KEY; - int ret; - - ldbg(__func__); - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); - if (ret) - dev_err(wm8350->dev, "lock failed\n"); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_lock); - -/** - * wm8350_reg_unlock() - * - * The WM8350 has a hardware lock which can be used to prevent writes to - * some registers (generally those which can cause particularly serious - * problems if misused). This function disables that lock so updates - * can be performed. For maximum safety this should be done only when - * required. - */ -int wm8350_reg_unlock(struct wm8350 *wm8350) -{ - u16 key = WM8350_UNLOCK_KEY; - int ret; - - ldbg(__func__); - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); - if (ret) - dev_err(wm8350->dev, "unlock failed\n"); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_unlock); - -int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) -{ - u16 reg, result = 0; - - if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) - return -EINVAL; - if (channel >= WM8350_AUXADC_USB && channel <= WM8350_AUXADC_TEMP - && (scale != 0 || vref != 0)) - return -EINVAL; - - mutex_lock(&wm8350->auxadc_mutex); - - /* Turn on the ADC */ - reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); - wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5, reg | WM8350_AUXADC_ENA); - - if (scale || vref) { - reg = scale << 13; - reg |= vref << 12; - wm8350_reg_write(wm8350, WM8350_AUX1_READBACK + channel, reg); - } - - reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - reg |= 1 << channel | WM8350_AUXADC_POLL; - wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); - - /* If a late IRQ left the completion signalled then consume - * the completion. */ - try_wait_for_completion(&wm8350->auxadc_done); - - /* We ignore the result of the completion and just check for a - * conversion result, allowing us to soldier on if the IRQ - * infrastructure is not set up for the chip. */ - wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5)); - - reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - if (reg & WM8350_AUXADC_POLL) - dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); - else - result = wm8350_reg_read(wm8350, - WM8350_AUX1_READBACK + channel); - - /* Turn off the ADC */ - reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); - wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5, - reg & ~WM8350_AUXADC_ENA); - - mutex_unlock(&wm8350->auxadc_mutex); - - return result & WM8350_AUXADC_DATA1_MASK; -} -EXPORT_SYMBOL_GPL(wm8350_read_auxadc); - -static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data) -{ - struct wm8350 *wm8350 = irq_data; - - complete(&wm8350->auxadc_done); - - return IRQ_HANDLED; -} - -/* - * Cache is always host endian. - */ -static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) -{ - int i, ret = 0; - u16 value; - const u16 *reg_map; - - switch (type) { - case 0: - switch (mode) { -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_0 - case 0: - reg_map = wm8350_mode0_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_1 - case 1: - reg_map = wm8350_mode1_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_2 - case 2: - reg_map = wm8350_mode2_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_3 - case 3: - reg_map = wm8350_mode3_defaults; - break; -#endif - default: - dev_err(wm8350->dev, - "WM8350 configuration mode %d not supported\n", - mode); - return -EINVAL; - } - break; - - case 1: - switch (mode) { -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_0 - case 0: - reg_map = wm8351_mode0_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_1 - case 1: - reg_map = wm8351_mode1_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_2 - case 2: - reg_map = wm8351_mode2_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_3 - case 3: - reg_map = wm8351_mode3_defaults; - break; -#endif - default: - dev_err(wm8350->dev, - "WM8351 configuration mode %d not supported\n", - mode); - return -EINVAL; - } - break; - - case 2: - switch (mode) { -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_0 - case 0: - reg_map = wm8352_mode0_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_1 - case 1: - reg_map = wm8352_mode1_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_2 - case 2: - reg_map = wm8352_mode2_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_3 - case 3: - reg_map = wm8352_mode3_defaults; - break; -#endif - default: - dev_err(wm8350->dev, - "WM8352 configuration mode %d not supported\n", - mode); - return -EINVAL; - } - break; - - default: - dev_err(wm8350->dev, - "WM835x configuration mode %d not supported\n", - mode); - return -EINVAL; - } - - wm8350->reg_cache = - kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL); - if (wm8350->reg_cache == NULL) - return -ENOMEM; - - /* Read the initial cache state back from the device - this is - * a PMIC so the device many not be in a virgin state and we - * can't rely on the silicon values. - */ - ret = wm8350->read_dev(wm8350, 0, - sizeof(u16) * (WM8350_MAX_REGISTER + 1), - wm8350->reg_cache); - if (ret < 0) { - dev_err(wm8350->dev, - "failed to read initial cache values\n"); - goto out; - } - - /* Mask out uncacheable/unreadable bits and the audio. */ - for (i = 0; i < WM8350_MAX_REGISTER; i++) { - if (wm8350_reg_io_map[i].readable && - (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { - value = be16_to_cpu(wm8350->reg_cache[i]); - value &= wm8350_reg_io_map[i].readable; - wm8350->reg_cache[i] = value; - } else - wm8350->reg_cache[i] = reg_map[i]; - } - -out: - kfree(wm8350->reg_cache); - return ret; -} - -/* - * Register a client device. This is non-fatal since there is no need to - * fail the entire device init due to a single platform device failing. - */ -static void wm8350_client_dev_register(struct wm8350 *wm8350, - const char *name, - struct platform_device **pdev) -{ - int ret; - - *pdev = platform_device_alloc(name, -1); - if (*pdev == NULL) { - dev_err(wm8350->dev, "Failed to allocate %s\n", name); - return; - } - - (*pdev)->dev.parent = wm8350->dev; - platform_set_drvdata(*pdev, wm8350); - ret = platform_device_add(*pdev); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to register %s: %d\n", name, ret); - platform_device_put(*pdev); - *pdev = NULL; - } -} - -int wm8350_device_init(struct wm8350 *wm8350, int irq, - struct wm8350_platform_data *pdata) -{ - int ret; - u16 id1, id2, mask_rev; - u16 cust_id, mode, chip_rev; - - dev_set_drvdata(wm8350->dev, wm8350); - - /* get WM8350 revision and config mode */ - ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); - goto err; - } - - ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); - goto err; - } - - ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), - &mask_rev); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); - goto err; - } - - id1 = be16_to_cpu(id1); - id2 = be16_to_cpu(id2); - mask_rev = be16_to_cpu(mask_rev); - - if (id1 != 0x6143) { - dev_err(wm8350->dev, - "Device with ID %x is not a WM8350\n", id1); - ret = -ENODEV; - goto err; - } - - mode = id2 & WM8350_CONF_STS_MASK >> 10; - cust_id = id2 & WM8350_CUST_ID_MASK; - chip_rev = (id2 & WM8350_CHIP_REV_MASK) >> 12; - dev_info(wm8350->dev, - "CONF_STS %d, CUST_ID %d, MASK_REV %d, CHIP_REV %d\n", - mode, cust_id, mask_rev, chip_rev); - - if (cust_id != 0) { - dev_err(wm8350->dev, "Unsupported CUST_ID\n"); - ret = -ENODEV; - goto err; - } - - switch (mask_rev) { - case 0: - wm8350->pmic.max_dcdc = WM8350_DCDC_6; - wm8350->pmic.max_isink = WM8350_ISINK_B; - - switch (chip_rev) { - case WM8350_REV_E: - dev_info(wm8350->dev, "WM8350 Rev E\n"); - break; - case WM8350_REV_F: - dev_info(wm8350->dev, "WM8350 Rev F\n"); - break; - case WM8350_REV_G: - dev_info(wm8350->dev, "WM8350 Rev G\n"); - wm8350->power.rev_g_coeff = 1; - break; - case WM8350_REV_H: - dev_info(wm8350->dev, "WM8350 Rev H\n"); - wm8350->power.rev_g_coeff = 1; - break; - default: - /* For safety we refuse to run on unknown hardware */ - dev_err(wm8350->dev, "Unknown WM8350 CHIP_REV\n"); - ret = -ENODEV; - goto err; - } - break; - - case 1: - wm8350->pmic.max_dcdc = WM8350_DCDC_4; - wm8350->pmic.max_isink = WM8350_ISINK_A; - - switch (chip_rev) { - case 0: - dev_info(wm8350->dev, "WM8351 Rev A\n"); - wm8350->power.rev_g_coeff = 1; - break; - - case 1: - dev_info(wm8350->dev, "WM8351 Rev B\n"); - wm8350->power.rev_g_coeff = 1; - break; - - default: - dev_err(wm8350->dev, "Unknown WM8351 CHIP_REV\n"); - ret = -ENODEV; - goto err; - } - break; - - case 2: - wm8350->pmic.max_dcdc = WM8350_DCDC_6; - wm8350->pmic.max_isink = WM8350_ISINK_B; - - switch (chip_rev) { - case 0: - dev_info(wm8350->dev, "WM8352 Rev A\n"); - wm8350->power.rev_g_coeff = 1; - break; - - default: - dev_err(wm8350->dev, "Unknown WM8352 CHIP_REV\n"); - ret = -ENODEV; - goto err; - } - break; - - default: - dev_err(wm8350->dev, "Unknown MASK_REV\n"); - ret = -ENODEV; - goto err; - } - - ret = wm8350_create_cache(wm8350, mask_rev, mode); - if (ret < 0) { - dev_err(wm8350->dev, "Failed to create register cache\n"); - return ret; - } - - mutex_init(&wm8350->auxadc_mutex); - init_completion(&wm8350->auxadc_done); - - ret = wm8350_irq_init(wm8350, irq, pdata); - if (ret < 0) - goto err_free; - - if (wm8350->irq_base) { - ret = request_threaded_irq(wm8350->irq_base + - WM8350_IRQ_AUXADC_DATARDY, - NULL, wm8350_auxadc_irq, 0, - "auxadc", wm8350); - if (ret < 0) - dev_warn(wm8350->dev, - "Failed to request AUXADC IRQ: %d\n", ret); - } - - if (pdata && pdata->init) { - ret = pdata->init(wm8350); - if (ret != 0) { - dev_err(wm8350->dev, "Platform init() failed: %d\n", - ret); - goto err_irq; - } - } - - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0); - - wm8350_client_dev_register(wm8350, "wm8350-codec", - &(wm8350->codec.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-gpio", - &(wm8350->gpio.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-hwmon", - &(wm8350->hwmon.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-power", - &(wm8350->power.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-wdt", &(wm8350->wdt.pdev)); - - return 0; - -err_irq: - wm8350_irq_exit(wm8350); -err_free: - kfree(wm8350->reg_cache); -err: - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_device_init); - -void wm8350_device_exit(struct wm8350 *wm8350) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wm8350->pmic.led); i++) - platform_device_unregister(wm8350->pmic.led[i].pdev); - - for (i = 0; i < ARRAY_SIZE(wm8350->pmic.pdev); i++) - platform_device_unregister(wm8350->pmic.pdev[i]); - - platform_device_unregister(wm8350->wdt.pdev); - platform_device_unregister(wm8350->rtc.pdev); - platform_device_unregister(wm8350->power.pdev); - platform_device_unregister(wm8350->hwmon.pdev); - platform_device_unregister(wm8350->gpio.pdev); - platform_device_unregister(wm8350->codec.pdev); - - if (wm8350->irq_base) - free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); - - wm8350_irq_exit(wm8350); - - kfree(wm8350->reg_cache); -} -EXPORT_SYMBOL_GPL(wm8350_device_exit); - -MODULE_DESCRIPTION("WM8350 AudioPlus PMIC core driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8350-gpio.c b/ANDROID_3.4.5/drivers/mfd/wm8350-gpio.c deleted file mode 100644 index d584f6b4..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8350-gpio.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * wm8350-core.c -- Device access for Wolfson WM8350 - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/errno.h> - -#include <linux/mfd/wm8350/core.h> -#include <linux/mfd/wm8350/gpio.h> -#include <linux/mfd/wm8350/pmic.h> - -static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir) -{ - int ret; - - wm8350_reg_unlock(wm8350); - if (dir == WM8350_GPIO_DIR_OUT) - ret = wm8350_clear_bits(wm8350, - WM8350_GPIO_CONFIGURATION_I_O, - 1 << gpio); - else - ret = wm8350_set_bits(wm8350, - WM8350_GPIO_CONFIGURATION_I_O, - 1 << gpio); - wm8350_reg_lock(wm8350); - return ret; -} - -static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db) -{ - if (db == WM8350_GPIO_DEBOUNCE_ON) - return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_DEBOUNCE, 1 << gpio); -} - -static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func) -{ - u16 reg; - - wm8350_reg_unlock(wm8350); - switch (gpio) { - case 0: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP0_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 0)); - break; - case 1: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP1_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 4)); - break; - case 2: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP2_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 8)); - break; - case 3: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP3_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 12)); - break; - case 4: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP4_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 0)); - break; - case 5: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP5_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 4)); - break; - case 6: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP6_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 8)); - break; - case 7: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP7_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 12)); - break; - case 8: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP8_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 0)); - break; - case 9: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP9_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 4)); - break; - case 10: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP10_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 8)); - break; - case 11: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP11_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 12)); - break; - case 12: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4) - & ~WM8350_GP12_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4, - reg | ((func & 0xf) << 0)); - break; - default: - wm8350_reg_lock(wm8350); - return -EINVAL; - } - - wm8350_reg_lock(wm8350); - return 0; -} - -static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up) -{ - if (up) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PIN_PULL_UP_CONTROL, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PIN_PULL_UP_CONTROL, - 1 << gpio); -} - -static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down) -{ - if (down) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PULL_DOWN_CONTROL, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PULL_DOWN_CONTROL, - 1 << gpio); -} - -static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol) -{ - if (pol == WM8350_GPIO_ACTIVE_HIGH) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PIN_POLARITY_TYPE, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PIN_POLARITY_TYPE, - 1 << gpio); -} - -static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert) -{ - if (invert == WM8350_GPIO_INVERT_ON) - return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_MODE, 1 << gpio); -} - -int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func, - int pol, int pull, int invert, int debounce) -{ - /* make sure we never pull up and down at the same time */ - if (pull == WM8350_GPIO_PULL_NONE) { - if (gpio_set_pull_up(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_down(wm8350, gpio, 0)) - goto err; - } else if (pull == WM8350_GPIO_PULL_UP) { - if (gpio_set_pull_down(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_up(wm8350, gpio, 1)) - goto err; - } else if (pull == WM8350_GPIO_PULL_DOWN) { - if (gpio_set_pull_up(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_down(wm8350, gpio, 1)) - goto err; - } - - if (gpio_set_invert(wm8350, gpio, invert)) - goto err; - if (gpio_set_polarity(wm8350, gpio, pol)) - goto err; - if (wm8350_gpio_set_debounce(wm8350, gpio, debounce)) - goto err; - if (gpio_set_dir(wm8350, gpio, dir)) - goto err; - return gpio_set_func(wm8350, gpio, func); - -err: - return -EIO; -} -EXPORT_SYMBOL_GPL(wm8350_gpio_config); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8350-i2c.c b/ANDROID_3.4.5/drivers/mfd/wm8350-i2c.c deleted file mode 100644 index d955faaf..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8350-i2c.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * wm8350-i2c.c -- Generic I2C driver for Wolfson WM8350 PMIC - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/platform_device.h> -#include <linux/mfd/wm8350/core.h> -#include <linux/slab.h> - -static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, - int bytes, void *dest) -{ - int ret; - - ret = i2c_master_send(wm8350->i2c_client, ®, 1); - if (ret < 0) - return ret; - ret = i2c_master_recv(wm8350->i2c_client, dest, bytes); - if (ret < 0) - return ret; - if (ret != bytes) - return -EIO; - return 0; -} - -static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, - int bytes, void *src) -{ - /* we add 1 byte for device register */ - u8 msg[(WM8350_MAX_REGISTER << 1) + 1]; - int ret; - - if (bytes > ((WM8350_MAX_REGISTER << 1) + 1)) - return -EINVAL; - - msg[0] = reg; - memcpy(&msg[1], src, bytes); - ret = i2c_master_send(wm8350->i2c_client, msg, bytes + 1); - if (ret < 0) - return ret; - if (ret != bytes + 1) - return -EIO; - return 0; -} - -static int wm8350_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8350 *wm8350; - int ret = 0; - - wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL); - if (wm8350 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm8350); - wm8350->dev = &i2c->dev; - wm8350->i2c_client = i2c; - wm8350->read_dev = wm8350_i2c_read_device; - wm8350->write_dev = wm8350_i2c_write_device; - - ret = wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data); - if (ret < 0) - goto err; - - return ret; - -err: - return ret; -} - -static int wm8350_i2c_remove(struct i2c_client *i2c) -{ - struct wm8350 *wm8350 = i2c_get_clientdata(i2c); - - wm8350_device_exit(wm8350); - - return 0; -} - -static const struct i2c_device_id wm8350_i2c_id[] = { - { "wm8350", 0 }, - { "wm8351", 0 }, - { "wm8352", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); - - -static struct i2c_driver wm8350_i2c_driver = { - .driver = { - .name = "wm8350", - .owner = THIS_MODULE, - }, - .probe = wm8350_i2c_probe, - .remove = wm8350_i2c_remove, - .id_table = wm8350_i2c_id, -}; - -static int __init wm8350_i2c_init(void) -{ - return i2c_add_driver(&wm8350_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(wm8350_i2c_init); - -static void __exit wm8350_i2c_exit(void) -{ - i2c_del_driver(&wm8350_i2c_driver); -} -module_exit(wm8350_i2c_exit); - -MODULE_DESCRIPTION("I2C support for the WM8350 AudioPlus PMIC"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8350-irq.c b/ANDROID_3.4.5/drivers/mfd/wm8350-irq.c deleted file mode 100644 index 9fd01bf6..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8350-irq.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * wm8350-irq.c -- IRQ support for Wolfson WM8350 - * - * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood, Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/bug.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> - -#include <linux/mfd/wm8350/core.h> -#include <linux/mfd/wm8350/audio.h> -#include <linux/mfd/wm8350/comparator.h> -#include <linux/mfd/wm8350/gpio.h> -#include <linux/mfd/wm8350/pmic.h> -#include <linux/mfd/wm8350/rtc.h> -#include <linux/mfd/wm8350/supply.h> -#include <linux/mfd/wm8350/wdt.h> - -#define WM8350_INT_OFFSET_1 0 -#define WM8350_INT_OFFSET_2 1 -#define WM8350_POWER_UP_INT_OFFSET 2 -#define WM8350_UNDER_VOLTAGE_INT_OFFSET 3 -#define WM8350_OVER_CURRENT_INT_OFFSET 4 -#define WM8350_GPIO_INT_OFFSET 5 -#define WM8350_COMPARATOR_INT_OFFSET 6 - -struct wm8350_irq_data { - int primary; - int reg; - int mask; - int primary_only; -}; - -static struct wm8350_irq_data wm8350_irqs[] = { - [WM8350_IRQ_OC_LS] = { - .primary = WM8350_OC_INT, - .reg = WM8350_OVER_CURRENT_INT_OFFSET, - .mask = WM8350_OC_LS_EINT, - .primary_only = 1, - }, - [WM8350_IRQ_UV_DC1] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC1_EINT, - }, - [WM8350_IRQ_UV_DC2] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC2_EINT, - }, - [WM8350_IRQ_UV_DC3] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC3_EINT, - }, - [WM8350_IRQ_UV_DC4] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC4_EINT, - }, - [WM8350_IRQ_UV_DC5] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC5_EINT, - }, - [WM8350_IRQ_UV_DC6] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_DC6_EINT, - }, - [WM8350_IRQ_UV_LDO1] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_LDO1_EINT, - }, - [WM8350_IRQ_UV_LDO2] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_LDO2_EINT, - }, - [WM8350_IRQ_UV_LDO3] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_LDO3_EINT, - }, - [WM8350_IRQ_UV_LDO4] = { - .primary = WM8350_UV_INT, - .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET, - .mask = WM8350_UV_LDO4_EINT, - }, - [WM8350_IRQ_CHG_BAT_HOT] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_BAT_HOT_EINT, - }, - [WM8350_IRQ_CHG_BAT_COLD] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_BAT_COLD_EINT, - }, - [WM8350_IRQ_CHG_BAT_FAIL] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_BAT_FAIL_EINT, - }, - [WM8350_IRQ_CHG_TO] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_TO_EINT, - }, - [WM8350_IRQ_CHG_END] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_END_EINT, - }, - [WM8350_IRQ_CHG_START] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_START_EINT, - }, - [WM8350_IRQ_CHG_FAST_RDY] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_FAST_RDY_EINT, - }, - [WM8350_IRQ_CHG_VBATT_LT_3P9] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_VBATT_LT_3P9_EINT, - }, - [WM8350_IRQ_CHG_VBATT_LT_3P1] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_VBATT_LT_3P1_EINT, - }, - [WM8350_IRQ_CHG_VBATT_LT_2P85] = { - .primary = WM8350_CHG_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_CHG_VBATT_LT_2P85_EINT, - }, - [WM8350_IRQ_RTC_ALM] = { - .primary = WM8350_RTC_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_RTC_ALM_EINT, - }, - [WM8350_IRQ_RTC_SEC] = { - .primary = WM8350_RTC_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_RTC_SEC_EINT, - }, - [WM8350_IRQ_RTC_PER] = { - .primary = WM8350_RTC_INT, - .reg = WM8350_INT_OFFSET_1, - .mask = WM8350_RTC_PER_EINT, - }, - [WM8350_IRQ_CS1] = { - .primary = WM8350_CS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_CS1_EINT, - }, - [WM8350_IRQ_CS2] = { - .primary = WM8350_CS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_CS2_EINT, - }, - [WM8350_IRQ_SYS_HYST_COMP_FAIL] = { - .primary = WM8350_SYS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_SYS_HYST_COMP_FAIL_EINT, - }, - [WM8350_IRQ_SYS_CHIP_GT115] = { - .primary = WM8350_SYS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_SYS_CHIP_GT115_EINT, - }, - [WM8350_IRQ_SYS_CHIP_GT140] = { - .primary = WM8350_SYS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_SYS_CHIP_GT140_EINT, - }, - [WM8350_IRQ_SYS_WDOG_TO] = { - .primary = WM8350_SYS_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_SYS_WDOG_TO_EINT, - }, - [WM8350_IRQ_AUXADC_DATARDY] = { - .primary = WM8350_AUXADC_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_AUXADC_DATARDY_EINT, - }, - [WM8350_IRQ_AUXADC_DCOMP4] = { - .primary = WM8350_AUXADC_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_AUXADC_DCOMP4_EINT, - }, - [WM8350_IRQ_AUXADC_DCOMP3] = { - .primary = WM8350_AUXADC_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_AUXADC_DCOMP3_EINT, - }, - [WM8350_IRQ_AUXADC_DCOMP2] = { - .primary = WM8350_AUXADC_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_AUXADC_DCOMP2_EINT, - }, - [WM8350_IRQ_AUXADC_DCOMP1] = { - .primary = WM8350_AUXADC_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_AUXADC_DCOMP1_EINT, - }, - [WM8350_IRQ_USB_LIMIT] = { - .primary = WM8350_USB_INT, - .reg = WM8350_INT_OFFSET_2, - .mask = WM8350_USB_LIMIT_EINT, - .primary_only = 1, - }, - [WM8350_IRQ_WKUP_OFF_STATE] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_OFF_STATE_EINT, - }, - [WM8350_IRQ_WKUP_HIB_STATE] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_HIB_STATE_EINT, - }, - [WM8350_IRQ_WKUP_CONV_FAULT] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_CONV_FAULT_EINT, - }, - [WM8350_IRQ_WKUP_WDOG_RST] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_WDOG_RST_EINT, - }, - [WM8350_IRQ_WKUP_GP_PWR_ON] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_GP_PWR_ON_EINT, - }, - [WM8350_IRQ_WKUP_ONKEY] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_ONKEY_EINT, - }, - [WM8350_IRQ_WKUP_GP_WAKEUP] = { - .primary = WM8350_WKUP_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_WKUP_GP_WAKEUP_EINT, - }, - [WM8350_IRQ_CODEC_JCK_DET_L] = { - .primary = WM8350_CODEC_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_CODEC_JCK_DET_L_EINT, - }, - [WM8350_IRQ_CODEC_JCK_DET_R] = { - .primary = WM8350_CODEC_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_CODEC_JCK_DET_R_EINT, - }, - [WM8350_IRQ_CODEC_MICSCD] = { - .primary = WM8350_CODEC_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_CODEC_MICSCD_EINT, - }, - [WM8350_IRQ_CODEC_MICD] = { - .primary = WM8350_CODEC_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_CODEC_MICD_EINT, - }, - [WM8350_IRQ_EXT_USB_FB] = { - .primary = WM8350_EXT_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_EXT_USB_FB_EINT, - }, - [WM8350_IRQ_EXT_WALL_FB] = { - .primary = WM8350_EXT_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_EXT_WALL_FB_EINT, - }, - [WM8350_IRQ_EXT_BAT_FB] = { - .primary = WM8350_EXT_INT, - .reg = WM8350_COMPARATOR_INT_OFFSET, - .mask = WM8350_EXT_BAT_FB_EINT, - }, - [WM8350_IRQ_GPIO(0)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP0_EINT, - }, - [WM8350_IRQ_GPIO(1)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP1_EINT, - }, - [WM8350_IRQ_GPIO(2)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP2_EINT, - }, - [WM8350_IRQ_GPIO(3)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP3_EINT, - }, - [WM8350_IRQ_GPIO(4)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP4_EINT, - }, - [WM8350_IRQ_GPIO(5)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP5_EINT, - }, - [WM8350_IRQ_GPIO(6)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP6_EINT, - }, - [WM8350_IRQ_GPIO(7)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP7_EINT, - }, - [WM8350_IRQ_GPIO(8)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP8_EINT, - }, - [WM8350_IRQ_GPIO(9)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP9_EINT, - }, - [WM8350_IRQ_GPIO(10)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP10_EINT, - }, - [WM8350_IRQ_GPIO(11)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP11_EINT, - }, - [WM8350_IRQ_GPIO(12)] = { - .primary = WM8350_GP_INT, - .reg = WM8350_GPIO_INT_OFFSET, - .mask = WM8350_GP12_EINT, - }, -}; - -static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350, - int irq) -{ - return &wm8350_irqs[irq - wm8350->irq_base]; -} - -/* - * This is a threaded IRQ handler so can access I2C/SPI. Since all - * interrupts are clear on read the IRQ line will be reasserted and - * the physical IRQ will be handled again if another interrupt is - * asserted while we run - in the normal course of events this is a - * rare occurrence so we save I2C/SPI reads. We're also assuming that - * it's rare to get lots of interrupts firing simultaneously so try to - * minimise I/O. - */ -static irqreturn_t wm8350_irq(int irq, void *irq_data) -{ - struct wm8350 *wm8350 = irq_data; - u16 level_one; - u16 sub_reg[WM8350_NUM_IRQ_REGS]; - int read_done[WM8350_NUM_IRQ_REGS]; - struct wm8350_irq_data *data; - int i; - - level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS) - & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK); - - if (!level_one) - return IRQ_NONE; - - memset(&read_done, 0, sizeof(read_done)); - - for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) { - data = &wm8350_irqs[i]; - - if (!(level_one & data->primary)) - continue; - - if (!read_done[data->reg]) { - sub_reg[data->reg] = - wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 + - data->reg); - sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg]; - read_done[data->reg] = 1; - } - - if (sub_reg[data->reg] & data->mask) - handle_nested_irq(wm8350->irq_base + i); - } - - return IRQ_HANDLED; -} - -static void wm8350_irq_lock(struct irq_data *data) -{ - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - - mutex_lock(&wm8350->irq_lock); -} - -static void wm8350_irq_sync_unlock(struct irq_data *data) -{ - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - int i; - - for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { - /* If there's been a change in the mask write it back - * to the hardware. */ - if (wm8350->irq_masks[i] != - wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i]) - WARN_ON(wm8350_reg_write(wm8350, - WM8350_INT_STATUS_1_MASK + i, - wm8350->irq_masks[i])); - } - - mutex_unlock(&wm8350->irq_lock); -} - -static void wm8350_irq_enable(struct irq_data *data) -{ - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, - data->irq); - - wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; -} - -static void wm8350_irq_disable(struct irq_data *data) -{ - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, - data->irq); - - wm8350->irq_masks[irq_data->reg] |= irq_data->mask; -} - -static struct irq_chip wm8350_irq_chip = { - .name = "wm8350", - .irq_bus_lock = wm8350_irq_lock, - .irq_bus_sync_unlock = wm8350_irq_sync_unlock, - .irq_disable = wm8350_irq_disable, - .irq_enable = wm8350_irq_enable, -}; - -int wm8350_irq_init(struct wm8350 *wm8350, int irq, - struct wm8350_platform_data *pdata) -{ - int ret, cur_irq, i; - int flags = IRQF_ONESHOT; - int irq_base = -1; - - if (!irq) { - dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n"); - return 0; - } - - /* Mask top level interrupts */ - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); - - /* Mask all individual interrupts by default and cache the - * masks. We read the masks back since there are unwritable - * bits in the mask registers. */ - for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { - wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i, - 0xFFFF); - wm8350->irq_masks[i] = - wm8350_reg_read(wm8350, - WM8350_INT_STATUS_1_MASK + i); - } - - mutex_init(&wm8350->irq_lock); - wm8350->chip_irq = irq; - - if (pdata && pdata->irq_base > 0) - irq_base = pdata->irq_base; - - wm8350->irq_base = irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0); - if (wm8350->irq_base < 0) { - dev_warn(wm8350->dev, "Allocating irqs failed with %d\n", - wm8350->irq_base); - return 0; - } - - if (pdata && pdata->irq_high) { - flags |= IRQF_TRIGGER_HIGH; - - wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, - WM8350_IRQ_POL); - } else { - flags |= IRQF_TRIGGER_LOW; - - wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1, - WM8350_IRQ_POL); - } - - /* Register with genirq */ - for (cur_irq = wm8350->irq_base; - cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; - cur_irq++) { - irq_set_chip_data(cur_irq, wm8350); - irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); - - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(irq, NULL, wm8350_irq, flags, - "wm8350", wm8350); - if (ret != 0) - dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret); - - /* Allow interrupts to fire */ - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0); - - return ret; -} - -int wm8350_irq_exit(struct wm8350 *wm8350) -{ - free_irq(wm8350->chip_irq, wm8350); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/mfd/wm8350-regmap.c b/ANDROID_3.4.5/drivers/mfd/wm8350-regmap.c deleted file mode 100644 index e965139e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8350-regmap.c +++ /dev/null @@ -1,3435 +0,0 @@ -/* - * wm8350-regmap.c -- Wolfson Microelectronics WM8350 register map - * - * This file splits out the tables describing the defaults and access - * status of the WM8350 registers since they are rather large. - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/mfd/wm8350/core.h> - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_0 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode0_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0FFC, /* R134 - GPIO Configuration (i/o) */ - 0x0FFC, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0013, /* R140 - GPIO Function Select 1 */ - 0x0000, /* R141 - GPIO Function Select 2 */ - 0x0000, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0000, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0000, /* R186 - DCDC3 Control */ - 0x0000, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0000, /* R189 - DCDC4 Control */ - 0x0000, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0000, /* R195 - DCDC6 Control */ - 0x0000, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001B, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_1 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode1_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0014, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x00FB, /* R134 - GPIO Configuration (i/o) */ - 0x04FE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0312, /* R140 - GPIO Function Select 1 */ - 0x1003, /* R141 - GPIO Function Select 2 */ - 0x1331, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x0062, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0026, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0062, /* R189 - DCDC4 Control */ - 0x0400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0800, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x0006, /* R200 - LDO1 Control */ - 0x0400, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0006, /* R203 - LDO2 Control */ - 0x0400, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_2 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode2_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0014, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x08FB, /* R134 - GPIO Configuration (i/o) */ - 0x0CFE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0312, /* R140 - GPIO Function Select 1 */ - 0x0003, /* R141 - GPIO Function Select 2 */ - 0x2331, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x002E, /* R186 - DCDC3 Control */ - 0x0800, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x000E, /* R189 - DCDC4 Control */ - 0x0800, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0C00, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001A, /* R200 - LDO1 Control */ - 0x0800, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0010, /* R203 - LDO2 Control */ - 0x0800, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x000A, /* R206 - LDO3 Control */ - 0x0C00, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001A, /* R209 - LDO4 Control */ - 0x0800, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_3 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode3_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1000, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0A7B, /* R134 - GPIO Configuration (i/o) */ - 0x06FE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x1312, /* R140 - GPIO Function Select 1 */ - 0x1030, /* R141 - GPIO Function Select 2 */ - 0x2231, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x000E, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0026, /* R189 - DCDC4 Control */ - 0x0400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0400, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001C, /* R203 - LDO2 Control */ - 0x0400, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001C, /* R206 - LDO3 Control */ - 0x0400, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001F, /* R209 - LDO4 Control */ - 0x0400, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_0 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8351_mode0_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0001, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0FFC, /* R134 - GPIO Configuration (i/o) */ - 0x0FFC, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0013, /* R140 - GPIO Function Select 1 */ - 0x0000, /* R141 - GPIO Function Select 2 */ - 0x0000, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0000, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0000, /* R186 - DCDC3 Control */ - 0x0000, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0000, /* R189 - DCDC4 Control */ - 0x0000, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x0000, /* R195 */ - 0x0000, /* R196 */ - 0x0006, /* R197 */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001B, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 - FLL Test 1 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x1000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_1 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8351_mode1_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0001, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0204, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0CFB, /* R134 - GPIO Configuration (i/o) */ - 0x0C1F, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0300, /* R140 - GPIO Function Select 1 */ - 0x1110, /* R141 - GPIO Function Select 2 */ - 0x0013, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0C00, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0026, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0062, /* R189 - DCDC4 Control */ - 0x0800, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x000A, /* R195 */ - 0x1000, /* R196 */ - 0x0006, /* R197 */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x0006, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0010, /* R203 - LDO2 Control */ - 0x0C00, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001F, /* R206 - LDO3 Control */ - 0x0800, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x000A, /* R209 - LDO4 Control */ - 0x0800, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 - FLL Test 1 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x1000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x1000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_2 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8351_mode2_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0001, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0214, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0110, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x09FA, /* R134 - GPIO Configuration (i/o) */ - 0x0DF6, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x1310, /* R140 - GPIO Function Select 1 */ - 0x0003, /* R141 - GPIO Function Select 2 */ - 0x2000, /* R142 - GPIO Function Select 3 */ - 0x0000, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x001A, /* R180 - DCDC1 Control */ - 0x0800, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0056, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0026, /* R189 - DCDC4 Control */ - 0x0C00, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x0026, /* R195 */ - 0x0C00, /* R196 */ - 0x0006, /* R197 */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0400, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0010, /* R203 - LDO2 Control */ - 0x0C00, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x0015, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001A, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 - FLL Test 1 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x1000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8351_CONFIG_MODE_3 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8351_mode3_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0001, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0204, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0010, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0BFB, /* R134 - GPIO Configuration (i/o) */ - 0x0FFD, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0310, /* R140 - GPIO Function Select 1 */ - 0x0001, /* R141 - GPIO Function Select 2 */ - 0x2300, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0026, /* R186 - DCDC3 Control */ - 0x0800, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0062, /* R189 - DCDC4 Control */ - 0x1400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x0026, /* R195 */ - 0x0400, /* R196 */ - 0x0006, /* R197 */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x0006, /* R200 - LDO1 Control */ - 0x0C00, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0016, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x0019, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001A, /* R209 - LDO4 Control */ - 0x1000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 - FLL Test 1 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x1000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_0 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8352_mode0_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0002, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0FFC, /* R134 - GPIO Configuration (i/o) */ - 0x0FFC, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0013, /* R140 - GPIO Function Select 1 */ - 0x0000, /* R141 - GPIO Function Select 2 */ - 0x0000, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0000, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0000, /* R186 - DCDC3 Control */ - 0x0000, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0000, /* R189 - DCDC4 Control */ - 0x0000, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0000, /* R195 - DCDC6 Control */ - 0x0000, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001B, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x5000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ - 0x5100, /* R252 */ - 0x1000, /* R253 - DCDC6 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_1 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8352_mode1_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0002, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0204, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0BFB, /* R134 - GPIO Configuration (i/o) */ - 0x0FFF, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0300, /* R140 - GPIO Function Select 1 */ - 0x0000, /* R141 - GPIO Function Select 2 */ - 0x2300, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x0062, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0006, /* R186 - DCDC3 Control */ - 0x0800, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0006, /* R189 - DCDC4 Control */ - 0x0C00, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x1000, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x0002, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001A, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001F, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001F, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x5000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ - 0x5100, /* R252 */ - 0x1000, /* R253 - DCDC6 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_2 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8352_mode2_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0002, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0204, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x0110, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x09DA, /* R134 - GPIO Configuration (i/o) */ - 0x0DD6, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x1310, /* R140 - GPIO Function Select 1 */ - 0x0033, /* R141 - GPIO Function Select 2 */ - 0x2000, /* R142 - GPIO Function Select 3 */ - 0x0000, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0800, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0056, /* R186 - DCDC3 Control */ - 0x1800, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x000E, /* R189 - DCDC4 Control */ - 0x1000, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0C00, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0006, /* R203 - LDO2 Control */ - 0x0400, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001C, /* R206 - LDO3 Control */ - 0x1400, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001A, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x5000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ - 0x5100, /* R252 */ - 0x1000, /* R253 - DCDC6 Test Controls */ -}; -#endif - -#ifdef CONFIG_MFD_WM8352_CONFIG_MODE_3 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8352_mode3_defaults[] = { - 0x6143, /* R0 - Reset/ID */ - 0x0000, /* R1 - ID */ - 0x0002, /* R2 - Revision */ - 0x1C02, /* R3 - System Control 1 */ - 0x0204, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3A00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - OUT1L Volume */ - 0x00E4, /* R105 - OUT1R Volume */ - 0x00E4, /* R106 - OUT2L Volume */ - 0x02E4, /* R107 - OUT2R Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0010, /* R129 - GPIO Pin pull up Control */ - 0x0000, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0BFB, /* R134 - GPIO Configuration (i/o) */ - 0x0FFD, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0310, /* R140 - GPIO Function Select 1 */ - 0x0001, /* R141 - GPIO Function Select 2 */ - 0x2300, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x032D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x0006, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0050, /* R186 - DCDC3 Control */ - 0x0C00, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x000E, /* R189 - DCDC4 Control */ - 0x0400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0029, /* R195 - DCDC6 Control */ - 0x0800, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001D, /* R200 - LDO1 Control */ - 0x1000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0017, /* R203 - LDO2 Control */ - 0x1000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x0006, /* R206 - LDO3 Control */ - 0x1000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x0010, /* R209 - LDO4 Control */ - 0x1000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 - Security1 */ - 0x4000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 - Signal overrides */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 - Charger Overides/status */ - 0x0000, /* R227 - misc overrides */ - 0x0000, /* R228 - Supply overrides/status 1 */ - 0x0000, /* R229 - Supply overrides/status 2 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 - comparotor overrides */ - 0x0000, /* R232 */ - 0x0000, /* R233 - State Machine status */ - 0x1200, /* R234 */ - 0x0000, /* R235 */ - 0x8000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0003, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0004, /* R243 */ - 0x0300, /* R244 */ - 0x0000, /* R245 */ - 0x0200, /* R246 */ - 0x0000, /* R247 */ - 0x1000, /* R248 - DCDC1 Test Controls */ - 0x5000, /* R249 */ - 0x1000, /* R250 - DCDC3 Test Controls */ - 0x1000, /* R251 - DCDC4 Test Controls */ - 0x5100, /* R252 */ - 0x1000, /* R253 - DCDC6 Test Controls */ -}; -#endif - -/* - * Access masks. - */ - -const struct wm8350_reg_access wm8350_reg_io_map[] = { - /* read write volatile */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R0 - Reset/ID */ - { 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */ - { 0x007F, 0x0000, 0x0000 }, /* R2 - ROM Mask ID */ - { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */ - { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */ - { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */ - { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */ - { 0x0000, 0x0000, 0x0000 }, /* R7 */ - { 0xE537, 0xE537, 0xFFFF }, /* R8 - Power mgmt (1) */ - { 0x0FF3, 0x0FF3, 0xFFFF }, /* R9 - Power mgmt (2) */ - { 0x008F, 0x008F, 0xFFFF }, /* R10 - Power mgmt (3) */ - { 0x6D3C, 0x6D3C, 0xFFFF }, /* R11 - Power mgmt (4) */ - { 0x1F8F, 0x1F8F, 0xFFFF }, /* R12 - Power mgmt (5) */ - { 0x8F3F, 0x8F3F, 0xFFFF }, /* R13 - Power mgmt (6) */ - { 0x0003, 0x0003, 0xFFFF }, /* R14 - Power mgmt (7) */ - { 0x0000, 0x0000, 0x0000 }, /* R15 */ - { 0x7F7F, 0x7F7F, 0xFFFF }, /* R16 - RTC Seconds/Minutes */ - { 0x073F, 0x073F, 0xFFFF }, /* R17 - RTC Hours/Day */ - { 0x1F3F, 0x1F3F, 0xFFFF }, /* R18 - RTC Date/Month */ - { 0x3FFF, 0x00FF, 0xFFFF }, /* R19 - RTC Year */ - { 0x7F7F, 0x7F7F, 0x0000 }, /* R20 - Alarm Seconds/Minutes */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R21 - Alarm Hours/Day */ - { 0x1F3F, 0x1F3F, 0x0000 }, /* R22 - Alarm Date/Month */ - { 0xEF7F, 0xEA7F, 0xFFFF }, /* R23 - RTC Time Control */ - { 0x3BFF, 0x0000, 0xFFFF }, /* R24 - System Interrupts */ - { 0xFEE7, 0x0000, 0xFFFF }, /* R25 - Interrupt Status 1 */ - { 0x35FF, 0x0000, 0xFFFF }, /* R26 - Interrupt Status 2 */ - { 0x0F3F, 0x0000, 0xFFFF }, /* R27 - Power Up Interrupt Status */ - { 0x0F3F, 0x0000, 0xFFFF }, /* R28 - Under Voltage Interrupt status */ - { 0x8000, 0x0000, 0xFFFF }, /* R29 - Over Current Interrupt status */ - { 0x1FFF, 0x0000, 0xFFFF }, /* R30 - GPIO Interrupt Status */ - { 0xEF7F, 0x0000, 0xFFFF }, /* R31 - Comparator Interrupt Status */ - { 0x3FFF, 0x3FFF, 0x0000 }, /* R32 - System Interrupts Mask */ - { 0xFEE7, 0xFEE7, 0x0000 }, /* R33 - Interrupt Status 1 Mask */ - { 0xF5FF, 0xF5FF, 0x0000 }, /* R34 - Interrupt Status 2 Mask */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R35 - Power Up Interrupt Status Mask */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R36 - Under Voltage Int status Mask */ - { 0x8000, 0x8000, 0x0000 }, /* R37 - Over Current Int status Mask */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R38 - GPIO Interrupt Status Mask */ - { 0xEF7F, 0xEF7F, 0x0000 }, /* R39 - Comparator IntStatus Mask */ - { 0xC9F7, 0xC9F7, 0xFFFF }, /* R40 - Clock Control 1 */ - { 0x8001, 0x8001, 0x0000 }, /* R41 - Clock Control 2 */ - { 0xFFF7, 0xFFF7, 0xFFFF }, /* R42 - FLL Control 1 */ - { 0xFBFF, 0xFBFF, 0x0000 }, /* R43 - FLL Control 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R44 - FLL Control 3 */ - { 0x0033, 0x0033, 0x0000 }, /* R45 - FLL Control 4 */ - { 0x0000, 0x0000, 0x0000 }, /* R46 */ - { 0x0000, 0x0000, 0x0000 }, /* R47 */ - { 0x3033, 0x3033, 0x0000 }, /* R48 - DAC Control */ - { 0x0000, 0x0000, 0x0000 }, /* R49 */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R50 - DAC Digital Volume L */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R51 - DAC Digital Volume R */ - { 0x0000, 0x0000, 0x0000 }, /* R52 */ - { 0x0FFF, 0x0FFF, 0xFFFF }, /* R53 - DAC LR Rate */ - { 0x0017, 0x0017, 0x0000 }, /* R54 - DAC Clock Control */ - { 0x0000, 0x0000, 0x0000 }, /* R55 */ - { 0x0000, 0x0000, 0x0000 }, /* R56 */ - { 0x0000, 0x0000, 0x0000 }, /* R57 */ - { 0x4000, 0x4000, 0x0000 }, /* R58 - DAC Mute */ - { 0x7000, 0x7000, 0x0000 }, /* R59 - DAC Mute Volume */ - { 0x3C00, 0x3C00, 0x0000 }, /* R60 - DAC Side */ - { 0x0000, 0x0000, 0x0000 }, /* R61 */ - { 0x0000, 0x0000, 0x0000 }, /* R62 */ - { 0x0000, 0x0000, 0x0000 }, /* R63 */ - { 0x8303, 0x8303, 0xFFFF }, /* R64 - ADC Control */ - { 0x0000, 0x0000, 0x0000 }, /* R65 */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R66 - ADC Digital Volume L */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R67 - ADC Digital Volume R */ - { 0x0FFF, 0x0FFF, 0x0000 }, /* R68 - ADC Divider */ - { 0x0000, 0x0000, 0x0000 }, /* R69 */ - { 0x0FFF, 0x0FFF, 0xFFFF }, /* R70 - ADC LR Rate */ - { 0x0000, 0x0000, 0x0000 }, /* R71 */ - { 0x0707, 0x0707, 0xFFFF }, /* R72 - Input Control */ - { 0xC0C0, 0xC0C0, 0xFFFF }, /* R73 - IN3 Input Control */ - { 0xC09F, 0xC09F, 0xFFFF }, /* R74 - Mic Bias Control */ - { 0x0000, 0x0000, 0x0000 }, /* R75 */ - { 0x0F15, 0x0F15, 0xFFFF }, /* R76 - Output Control */ - { 0xC000, 0xC000, 0xFFFF }, /* R77 - Jack Detect */ - { 0x03FF, 0x03FF, 0x0000 }, /* R78 - Anti Pop Control */ - { 0x0000, 0x0000, 0x0000 }, /* R79 */ - { 0xE1FC, 0xE1FC, 0x8000 }, /* R80 - Left Input Volume */ - { 0xE1FC, 0xE1FC, 0x8000 }, /* R81 - Right Input Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R82 */ - { 0x0000, 0x0000, 0x0000 }, /* R83 */ - { 0x0000, 0x0000, 0x0000 }, /* R84 */ - { 0x0000, 0x0000, 0x0000 }, /* R85 */ - { 0x0000, 0x0000, 0x0000 }, /* R86 */ - { 0x0000, 0x0000, 0x0000 }, /* R87 */ - { 0x9807, 0x9807, 0xFFFF }, /* R88 - Left Mixer Control */ - { 0x980B, 0x980B, 0xFFFF }, /* R89 - Right Mixer Control */ - { 0x0000, 0x0000, 0x0000 }, /* R90 */ - { 0x0000, 0x0000, 0x0000 }, /* R91 */ - { 0x8909, 0x8909, 0xFFFF }, /* R92 - OUT3 Mixer Control */ - { 0x9E07, 0x9E07, 0xFFFF }, /* R93 - OUT4 Mixer Control */ - { 0x0000, 0x0000, 0x0000 }, /* R94 */ - { 0x0000, 0x0000, 0x0000 }, /* R95 */ - { 0x0EEE, 0x0EEE, 0x0000 }, /* R96 - Output Left Mixer Volume */ - { 0xE0EE, 0xE0EE, 0x0000 }, /* R97 - Output Right Mixer Volume */ - { 0x0E0F, 0x0E0F, 0x0000 }, /* R98 - Input Mixer Volume L */ - { 0xE0E1, 0xE0E1, 0x0000 }, /* R99 - Input Mixer Volume R */ - { 0x800E, 0x800E, 0x0000 }, /* R100 - Input Mixer Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R101 */ - { 0x0000, 0x0000, 0x0000 }, /* R102 */ - { 0x0000, 0x0000, 0x0000 }, /* R103 */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R104 - LOUT1 Volume */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R105 - ROUT1 Volume */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R106 - LOUT2 Volume */ - { 0xE7FC, 0xE7FC, 0xFFFF }, /* R107 - ROUT2 Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R108 */ - { 0x0000, 0x0000, 0x0000 }, /* R109 */ - { 0x0000, 0x0000, 0x0000 }, /* R110 */ - { 0x80E0, 0x80E0, 0xFFFF }, /* R111 - BEEP Volume */ - { 0xBF00, 0xBF00, 0x0000 }, /* R112 - AI Formating */ - { 0x00F1, 0x00F1, 0x0000 }, /* R113 - ADC DAC COMP */ - { 0x00F8, 0x00F8, 0x0000 }, /* R114 - AI ADC Control */ - { 0x40FB, 0x40FB, 0x0000 }, /* R115 - AI DAC Control */ - { 0x7C30, 0x7C30, 0x0000 }, /* R116 - AIF Test */ - { 0x0000, 0x0000, 0x0000 }, /* R117 */ - { 0x0000, 0x0000, 0x0000 }, /* R118 */ - { 0x0000, 0x0000, 0x0000 }, /* R119 */ - { 0x0000, 0x0000, 0x0000 }, /* R120 */ - { 0x0000, 0x0000, 0x0000 }, /* R121 */ - { 0x0000, 0x0000, 0x0000 }, /* R122 */ - { 0x0000, 0x0000, 0x0000 }, /* R123 */ - { 0x0000, 0x0000, 0x0000 }, /* R124 */ - { 0x0000, 0x0000, 0x0000 }, /* R125 */ - { 0x0000, 0x0000, 0x0000 }, /* R126 */ - { 0x0000, 0x0000, 0x0000 }, /* R127 */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R128 - GPIO Debounce */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R129 - GPIO Pin pull up Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R130 - GPIO Pull down Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R131 - GPIO Interrupt Mode */ - { 0x0000, 0x0000, 0x0000 }, /* R132 */ - { 0x00C0, 0x00C0, 0x0000 }, /* R133 - GPIO Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R134 - GPIO Configuration (i/o) */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R135 - GPIO Pin Polarity / Type */ - { 0x0000, 0x0000, 0x0000 }, /* R136 */ - { 0x0000, 0x0000, 0x0000 }, /* R137 */ - { 0x0000, 0x0000, 0x0000 }, /* R138 */ - { 0x0000, 0x0000, 0x0000 }, /* R139 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R140 - GPIO Function Select 1 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R141 - GPIO Function Select 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R142 - GPIO Function Select 3 */ - { 0x000F, 0x000F, 0x0000 }, /* R143 - GPIO Function Select 4 */ - { 0xF0FF, 0xF0FF, 0xA000 }, /* R144 - Digitiser Control (1) */ - { 0x3707, 0x3707, 0x0000 }, /* R145 - Digitiser Control (2) */ - { 0x0000, 0x0000, 0x0000 }, /* R146 */ - { 0x0000, 0x0000, 0x0000 }, /* R147 */ - { 0x0000, 0x0000, 0x0000 }, /* R148 */ - { 0x0000, 0x0000, 0x0000 }, /* R149 */ - { 0x0000, 0x0000, 0x0000 }, /* R150 */ - { 0x0000, 0x0000, 0x0000 }, /* R151 */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R152 - AUX1 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R153 - AUX2 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R154 - AUX3 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R155 - AUX4 Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R156 - USB Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R157 - LINE Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R158 - BATT Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R159 - Chip Temp Readback */ - { 0x0000, 0x0000, 0x0000 }, /* R160 */ - { 0x0000, 0x0000, 0x0000 }, /* R161 */ - { 0x0000, 0x0000, 0x0000 }, /* R162 */ - { 0x000F, 0x000F, 0x0000 }, /* R163 - Generic Comparator Control */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R164 - Generic comparator 1 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R165 - Generic comparator 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R166 - Generic comparator 3 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R167 - Generic comparator 4 */ - { 0xBFFF, 0xBFFF, 0x8000 }, /* R168 - Battery Charger Control 1 */ - { 0xFFFF, 0x4FFF, 0xB000 }, /* R169 - Battery Charger Control 2 */ - { 0x007F, 0x007F, 0x0000 }, /* R170 - Battery Charger Control 3 */ - { 0x0000, 0x0000, 0x0000 }, /* R171 */ - { 0x903F, 0x903F, 0xFFFF }, /* R172 - Current Sink Driver A */ - { 0xE333, 0xE333, 0xFFFF }, /* R173 - CSA Flash control */ - { 0x903F, 0x903F, 0xFFFF }, /* R174 - Current Sink Driver B */ - { 0xE333, 0xE333, 0xFFFF }, /* R175 - CSB Flash control */ - { 0x8F3F, 0x8F3F, 0xFFFF }, /* R176 - DCDC/LDO requested */ - { 0x332D, 0x332D, 0x0000 }, /* R177 - DCDC Active options */ - { 0x002D, 0x002D, 0x0000 }, /* R178 - DCDC Sleep options */ - { 0x5177, 0x5177, 0x8000 }, /* R179 - Power-check comparator */ - { 0x047F, 0x047F, 0x0000 }, /* R180 - DCDC1 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R181 - DCDC1 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R182 - DCDC1 Low Power */ - { 0x535B, 0x535B, 0x0000 }, /* R183 - DCDC2 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R184 - DCDC2 Timeouts */ - { 0x0000, 0x0000, 0x0000 }, /* R185 */ - { 0x047F, 0x047F, 0x0000 }, /* R186 - DCDC3 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R187 - DCDC3 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R188 - DCDC3 Low Power */ - { 0x047F, 0x047F, 0x0000 }, /* R189 - DCDC4 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R190 - DCDC4 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R191 - DCDC4 Low Power */ - { 0x535B, 0x535B, 0x0000 }, /* R192 - DCDC5 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R193 - DCDC5 Timeouts */ - { 0x0000, 0x0000, 0x0000 }, /* R194 */ - { 0x047F, 0x047F, 0x0000 }, /* R195 - DCDC6 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R196 - DCDC6 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R197 - DCDC6 Low Power */ - { 0x0000, 0x0000, 0x0000 }, /* R198 */ - { 0xFFD3, 0xFFD3, 0x0000 }, /* R199 - Limit Switch Control */ - { 0x441F, 0x441F, 0x0000 }, /* R200 - LDO1 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R201 - LDO1 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R202 - LDO1 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R203 - LDO2 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R204 - LDO2 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R205 - LDO2 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R206 - LDO3 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R207 - LDO3 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R208 - LDO3 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R209 - LDO4 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R210 - LDO4 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R211 - LDO4 Low Power */ - { 0x0000, 0x0000, 0x0000 }, /* R212 */ - { 0x0000, 0x0000, 0x0000 }, /* R213 */ - { 0x0000, 0x0000, 0x0000 }, /* R214 */ - { 0x8F3F, 0x8F3F, 0x0000 }, /* R215 - VCC_FAULT Masks */ - { 0xFF3F, 0xE03F, 0x0000 }, /* R216 - Main Bandgap Control */ - { 0xEF2F, 0xE02F, 0x0000 }, /* R217 - OSC Control */ - { 0xF3FF, 0xB3FF, 0xc000 }, /* R218 - RTC Tick Control */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R219 - Security */ - { 0x09FF, 0x01FF, 0x0000 }, /* R220 - RAM BIST 1 */ - { 0x0000, 0x0000, 0x0000 }, /* R221 */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R222 */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R223 */ - { 0x0000, 0x0000, 0x0000 }, /* R224 */ - { 0x8F3F, 0x0000, 0xFFFF }, /* R225 - DCDC/LDO status */ - { 0x0000, 0x0000, 0xFFFF }, /* R226 - Charger status */ - { 0x34FE, 0x0000, 0xFFFF }, /* R227 */ - { 0x0000, 0x0000, 0x0000 }, /* R228 */ - { 0x0000, 0x0000, 0x0000 }, /* R229 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R230 - GPIO Pin Status */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R231 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R232 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R233 */ - { 0x0000, 0x0000, 0x0000 }, /* R234 */ - { 0x0000, 0x0000, 0x0000 }, /* R235 */ - { 0x0000, 0x0000, 0x0000 }, /* R236 */ - { 0x0000, 0x0000, 0x0000 }, /* R237 */ - { 0x0000, 0x0000, 0x0000 }, /* R238 */ - { 0x0000, 0x0000, 0x0000 }, /* R239 */ - { 0x0000, 0x0000, 0x0000 }, /* R240 */ - { 0x0000, 0x0000, 0x0000 }, /* R241 */ - { 0x0000, 0x0000, 0x0000 }, /* R242 */ - { 0x0000, 0x0000, 0x0000 }, /* R243 */ - { 0x0000, 0x0000, 0x0000 }, /* R244 */ - { 0x0000, 0x0000, 0x0000 }, /* R245 */ - { 0x0000, 0x0000, 0x0000 }, /* R246 */ - { 0x0000, 0x0000, 0x0000 }, /* R247 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R248 */ - { 0x0000, 0x0000, 0x0000 }, /* R249 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R250 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R251 */ - { 0x0000, 0x0000, 0x0000 }, /* R252 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R253 */ - { 0x0000, 0x0000, 0x0000 }, /* R254 */ - { 0x0000, 0x0000, 0x0000 }, /* R255 */ -}; diff --git a/ANDROID_3.4.5/drivers/mfd/wm8400-core.c b/ANDROID_3.4.5/drivers/mfd/wm8400-core.c deleted file mode 100644 index 1189a17f..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8400-core.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Core driver for WM8400. - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ - -#include <linux/module.h> -#include <linux/bug.h> -#include <linux/err.h> -#include <linux/i2c.h> -#include <linux/kernel.h> -#include <linux/mfd/core.h> -#include <linux/mfd/wm8400-private.h> -#include <linux/mfd/wm8400-audio.h> -#include <linux/regmap.h> -#include <linux/slab.h> - -static struct { - u16 readable; /* Mask of readable bits */ - u16 writable; /* Mask of writable bits */ - u16 vol; /* Mask of volatile bits */ - int is_codec; /* Register controlled by codec reset */ - u16 default_val; /* Value on reset */ -} reg_data[] = { - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x6172 }, /* R0 */ - { 0x7000, 0x0000, 0x8000, 0, 0x0000 }, /* R1 */ - { 0xFF17, 0xFF17, 0x0000, 0, 0x0000 }, /* R2 */ - { 0xEBF3, 0xEBF3, 0x0000, 1, 0x6000 }, /* R3 */ - { 0x3CF3, 0x3CF3, 0x0000, 1, 0x0000 }, /* R4 */ - { 0xF1F8, 0xF1F8, 0x0000, 1, 0x4050 }, /* R5 */ - { 0xFC1F, 0xFC1F, 0x0000, 1, 0x4000 }, /* R6 */ - { 0xDFDE, 0xDFDE, 0x0000, 1, 0x01C8 }, /* R7 */ - { 0xFCFC, 0xFCFC, 0x0000, 1, 0x0000 }, /* R8 */ - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R9 */ - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R10 */ - { 0x27F7, 0x27F7, 0x0000, 1, 0x0004 }, /* R11 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R12 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R13 */ - { 0x1FEF, 0x1FEF, 0x0000, 1, 0x0000 }, /* R14 */ - { 0x0163, 0x0163, 0x0000, 1, 0x0100 }, /* R15 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R16 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R17 */ - { 0x1FFF, 0x0FFF, 0x0000, 1, 0x0000 }, /* R18 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1000 }, /* R19 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R20 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R21 */ - { 0x0FDD, 0x0FDD, 0x0000, 1, 0x8000 }, /* R22 */ - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0800 }, /* R23 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R24 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R25 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R26 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R27 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R28 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R29 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0066 }, /* R30 */ - { 0x0000, 0x0033, 0x0000, 1, 0x0022 }, /* R31 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R32 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R33 */ - { 0x0000, 0x0003, 0x0000, 1, 0x0003 }, /* R34 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0003 }, /* R35 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R36 */ - { 0x0000, 0x003F, 0x0000, 1, 0x0100 }, /* R37 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R38 */ - { 0x0000, 0x000F, 0x0000, 0, 0x0000 }, /* R39 */ - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R40 */ - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R41 */ - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R42 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R43 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R44 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R45 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R46 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R47 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R48 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R49 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R50 */ - { 0x0000, 0x01B3, 0x0000, 1, 0x0180 }, /* R51 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R52 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R53 */ - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R54 */ - { 0x0000, 0x0001, 0x0000, 1, 0x0000 }, /* R55 */ - { 0x0000, 0x003F, 0x0000, 1, 0x0000 }, /* R56 */ - { 0x0000, 0x004F, 0x0000, 1, 0x0000 }, /* R57 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R58 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R59 */ - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0000 }, /* R60 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x0000 }, /* R61 */ - { 0x03FF, 0x03FF, 0x0000, 1, 0x0000 }, /* R62 */ - { 0x007F, 0x007F, 0x0000, 1, 0x0000 }, /* R63 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R64 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R65 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R66 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R67 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R68 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R69 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R70 */ - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R71 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R72 */ - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R73 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R74 */ - { 0x000E, 0x000E, 0x0000, 0, 0x0008 }, /* R75 */ - { 0xE00F, 0xE00F, 0x0000, 0, 0x0000 }, /* R76 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R77 */ - { 0x03C0, 0x03C0, 0x0000, 0, 0x02C0 }, /* R78 */ - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R79 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x0000 }, /* R80 */ - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R81 */ - { 0x2BFF, 0x0000, 0xffff, 0, 0x0000 }, /* R82 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R83 */ - { 0x80FF, 0x80FF, 0x0000, 0, 0x00ff }, /* R84 */ -}; - -static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest) -{ - int i, ret = 0; - - BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); - - /* If there are any volatile reads then read back the entire block */ - for (i = reg; i < reg + num_regs; i++) - if (reg_data[i].vol) { - ret = regmap_bulk_read(wm8400->regmap, reg, dest, - num_regs); - return ret; - } - - /* Otherwise use the cache */ - memcpy(dest, &wm8400->reg_cache[reg], num_regs * sizeof(u16)); - - return 0; -} - -static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, - u16 *src) -{ - int ret, i; - - BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); - - for (i = 0; i < num_regs; i++) { - BUG_ON(!reg_data[reg + i].writable); - wm8400->reg_cache[reg + i] = src[i]; - ret = regmap_write(wm8400->regmap, reg, src[i]); - if (ret != 0) - return ret; - } - - return 0; -} - -/** - * wm8400_reg_read - Single register read - * - * @wm8400: Pointer to wm8400 control structure - * @reg: Register to read - * - * @return Read value - */ -u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg) -{ - u16 val; - - mutex_lock(&wm8400->io_lock); - - wm8400_read(wm8400, reg, 1, &val); - - mutex_unlock(&wm8400->io_lock); - - return val; -} -EXPORT_SYMBOL_GPL(wm8400_reg_read); - -int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) -{ - int ret; - - mutex_lock(&wm8400->io_lock); - - ret = wm8400_read(wm8400, reg, count, data); - - mutex_unlock(&wm8400->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm8400_block_read); - -/** - * wm8400_set_bits - Bitmask write - * - * @wm8400: Pointer to wm8400 control structure - * @reg: Register to access - * @mask: Mask of bits to change - * @val: Value to set for masked bits - */ -int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val) -{ - u16 tmp; - int ret; - - mutex_lock(&wm8400->io_lock); - - ret = wm8400_read(wm8400, reg, 1, &tmp); - tmp = (tmp & ~mask) | val; - if (ret == 0) - ret = wm8400_write(wm8400, reg, 1, &tmp); - - mutex_unlock(&wm8400->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm8400_set_bits); - -/** - * wm8400_reset_codec_reg_cache - Reset cached codec registers to - * their default values. - */ -void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) -{ - int i; - - mutex_lock(&wm8400->io_lock); - - /* Reset all codec registers to their initial value */ - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - if (reg_data[i].is_codec) - wm8400->reg_cache[i] = reg_data[i].default_val; - - mutex_unlock(&wm8400->io_lock); -} -EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); - -static int wm8400_register_codec(struct wm8400 *wm8400) -{ - struct mfd_cell cell = { - .name = "wm8400-codec", - .platform_data = wm8400, - .pdata_size = sizeof(*wm8400), - }; - - return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); -} - -/* - * wm8400_init - Generic initialisation - * - * The WM8400 can be configured as either an I2C or SPI device. Probe - * functions for each bus set up the accessors then call into this to - * set up the device itself. - */ -static int wm8400_init(struct wm8400 *wm8400, - struct wm8400_platform_data *pdata) -{ - u16 reg; - int ret, i; - - mutex_init(&wm8400->io_lock); - - dev_set_drvdata(wm8400->dev, wm8400); - - /* Check that this is actually a WM8400 */ - ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &i); - if (ret != 0) { - dev_err(wm8400->dev, "Chip ID register read failed\n"); - return -EIO; - } - if (i != reg_data[WM8400_RESET_ID].default_val) { - dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", i); - return -ENODEV; - } - - /* We don't know what state the hardware is in and since this - * is a PMIC we can't reset it safely so initialise the register - * cache from the hardware. - */ - ret = regmap_raw_read(wm8400->regmap, 0, wm8400->reg_cache, - ARRAY_SIZE(wm8400->reg_cache)); - if (ret != 0) { - dev_err(wm8400->dev, "Register cache read failed\n"); - return -EIO; - } - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]); - - /* If the codec is in reset use hard coded values */ - if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA)) - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - if (reg_data[i].is_codec) - wm8400->reg_cache[i] = reg_data[i].default_val; - - ret = wm8400_read(wm8400, WM8400_ID, 1, ®); - if (ret != 0) { - dev_err(wm8400->dev, "ID register read failed: %d\n", ret); - return ret; - } - reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT; - dev_info(wm8400->dev, "WM8400 revision %x\n", reg); - - ret = wm8400_register_codec(wm8400); - if (ret != 0) { - dev_err(wm8400->dev, "Failed to register codec\n"); - goto err_children; - } - - if (pdata && pdata->platform_init) { - ret = pdata->platform_init(wm8400->dev); - if (ret != 0) { - dev_err(wm8400->dev, "Platform init failed: %d\n", - ret); - goto err_children; - } - } else - dev_warn(wm8400->dev, "No platform initialisation supplied\n"); - - return 0; - -err_children: - mfd_remove_devices(wm8400->dev); - return ret; -} - -static void wm8400_release(struct wm8400 *wm8400) -{ - mfd_remove_devices(wm8400->dev); -} - -static const struct regmap_config wm8400_regmap_config = { - .reg_bits = 8, - .val_bits = 16, - .max_register = WM8400_REGISTER_COUNT - 1, -}; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int wm8400_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8400 *wm8400; - int ret; - - wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL); - if (wm8400 == NULL) { - ret = -ENOMEM; - goto err; - } - - wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config); - if (IS_ERR(wm8400->regmap)) { - ret = PTR_ERR(wm8400->regmap); - goto err; - } - - wm8400->dev = &i2c->dev; - i2c_set_clientdata(i2c, wm8400); - - ret = wm8400_init(wm8400, i2c->dev.platform_data); - if (ret != 0) - goto err; - - return 0; - -err: - return ret; -} - -static int wm8400_i2c_remove(struct i2c_client *i2c) -{ - struct wm8400 *wm8400 = i2c_get_clientdata(i2c); - - wm8400_release(wm8400); - - return 0; -} - -static const struct i2c_device_id wm8400_i2c_id[] = { - { "wm8400", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8400_i2c_id); - -static struct i2c_driver wm8400_i2c_driver = { - .driver = { - .name = "WM8400", - .owner = THIS_MODULE, - }, - .probe = wm8400_i2c_probe, - .remove = wm8400_i2c_remove, - .id_table = wm8400_i2c_id, -}; -#endif - -static int __init wm8400_module_init(void) -{ - int ret = -ENODEV; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8400_i2c_driver); - if (ret != 0) - pr_err("Failed to register I2C driver: %d\n", ret); -#endif - - return ret; -} -subsys_initcall(wm8400_module_init); - -static void __exit wm8400_module_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8400_i2c_driver); -#endif -} -module_exit(wm8400_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8994-core.c b/ANDROID_3.4.5/drivers/mfd/wm8994-core.c deleted file mode 100644 index 98ff03f5..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8994-core.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - * wm8994-core.c -- Device access for Wolfson WM8994 - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/err.h> -#include <linux/delay.h> -#include <linux/mfd/core.h> -#include <linux/pm_runtime.h> -#include <linux/regmap.h> -#include <linux/regulator/consumer.h> -#include <linux/regulator/machine.h> - -#include <linux/mfd/wm8994/core.h> -#include <linux/mfd/wm8994/pdata.h> -#include <linux/mfd/wm8994/registers.h> - -#include "wm8994.h" - -/** - * wm8994_reg_read: Read a single WM8994 register. - * - * @wm8994: Device to read from. - * @reg: Register to read. - */ -int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg) -{ - unsigned int val; - int ret; - - ret = regmap_read(wm8994->regmap, reg, &val); - - if (ret < 0) - return ret; - else - return val; -} -EXPORT_SYMBOL_GPL(wm8994_reg_read); - -/** - * wm8994_bulk_read: Read multiple WM8994 registers - * - * @wm8994: Device to read from - * @reg: First register - * @count: Number of registers - * @buf: Buffer to fill. The data will be returned big endian. - */ -int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, - int count, u16 *buf) -{ - return regmap_bulk_read(wm8994->regmap, reg, buf, count); -} - -/** - * wm8994_reg_write: Write a single WM8994 register. - * - * @wm8994: Device to write to. - * @reg: Register to write to. - * @val: Value to write. - */ -int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, - unsigned short val) -{ - return regmap_write(wm8994->regmap, reg, val); -} -EXPORT_SYMBOL_GPL(wm8994_reg_write); - -/** - * wm8994_bulk_write: Write multiple WM8994 registers - * - * @wm8994: Device to write to - * @reg: First register - * @count: Number of registers - * @buf: Buffer to write from. Data must be big-endian formatted. - */ -int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, - int count, const u16 *buf) -{ - return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16)); -} -EXPORT_SYMBOL_GPL(wm8994_bulk_write); - -/** - * wm8994_set_bits: Set the value of a bitfield in a WM8994 register - * - * @wm8994: Device to write to. - * @reg: Register to write to. - * @mask: Mask of bits to set. - * @val: Value to set (unshifted) - */ -int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, - unsigned short mask, unsigned short val) -{ - return regmap_update_bits(wm8994->regmap, reg, mask, val); -} -EXPORT_SYMBOL_GPL(wm8994_set_bits); - -static struct mfd_cell wm8994_regulator_devs[] = { - { - .name = "wm8994-ldo", - .id = 1, - .pm_runtime_no_callbacks = true, - }, - { - .name = "wm8994-ldo", - .id = 2, - .pm_runtime_no_callbacks = true, - }, -}; - -static struct resource wm8994_codec_resources[] = { - { - .start = WM8994_IRQ_TEMP_SHUT, - .end = WM8994_IRQ_TEMP_WARN, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource wm8994_gpio_resources[] = { - { - .start = WM8994_IRQ_GPIO(1), - .end = WM8994_IRQ_GPIO(11), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell wm8994_devs[] = { - { - .name = "wm8994-codec", - .num_resources = ARRAY_SIZE(wm8994_codec_resources), - .resources = wm8994_codec_resources, - }, - - { - .name = "wm8994-gpio", - .num_resources = ARRAY_SIZE(wm8994_gpio_resources), - .resources = wm8994_gpio_resources, - .pm_runtime_no_callbacks = true, - }, -}; - -/* - * Supplies for the main bulk of CODEC; the LDO supplies are ignored - * and should be handled via the standard regulator API supply - * management. - */ -static const char *wm1811_main_supplies[] = { - "DBVDD1", - "DBVDD2", - "DBVDD3", - "DCVDD", - "AVDD1", - "AVDD2", - "CPVDD", - "SPKVDD1", - "SPKVDD2", -}; - -static const char *wm8994_main_supplies[] = { - "DBVDD", - "DCVDD", - "AVDD1", - "AVDD2", - "CPVDD", - "SPKVDD1", - "SPKVDD2", -}; - -static const char *wm8958_main_supplies[] = { - "DBVDD1", - "DBVDD2", - "DBVDD3", - "DCVDD", - "AVDD1", - "AVDD2", - "CPVDD", - "SPKVDD1", - "SPKVDD2", -}; - -#ifdef CONFIG_PM -static int wm8994_suspend(struct device *dev) -{ - struct wm8994 *wm8994 = dev_get_drvdata(dev); - int ret; - - /* Don't actually go through with the suspend if the CODEC is - * still active (eg, for audio passthrough from CP. */ - ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); - if (ret < 0) { - dev_err(dev, "Failed to read power status: %d\n", ret); - } else if (ret & WM8994_VMID_SEL_MASK) { - dev_warn(dev, "CODEC still active, ignoring suspend [%d]\n", __LINE__); - 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_warn(dev, "CODEC still active, ignoring suspend [%d]\n", __LINE__); - 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_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA | - WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) { - dev_warn(dev, "CODEC still active, ignoring suspend [%d]\n", __LINE__); - return 0; - } - - switch (wm8994->type) { - case WM8958: - case WM1811: - 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_warn(dev, "CODEC still active, ignoring suspend\n"); - return 0; - } - break; - default: - break; - } - - switch (wm8994->type) { - case WM1811: - ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); - if (ret < 0) { - dev_err(dev, "Failed to read jackdet: %d\n", ret); - } else if (ret & WM1811_JACKDET_MODE_MASK) { - dev_warn(dev, "CODEC still active, ignoring suspend\n"); - return 0; - } - break; - default: - break; - } - - switch (wm8994->type) { - case WM1811: - ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); - if (ret < 0) { - dev_err(dev, "Failed to read jackdet: %d\n", ret); - } else if (ret & WM1811_JACKDET_MODE_MASK) { - dev_warn(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); - - /* Explicitly put the device into reset in case regulators - * don't get disabled in order to ensure consistent restart. - */ - wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, - wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); - - regcache_cache_only(wm8994->regmap, true); - regcache_mark_dirty(wm8994->regmap); - - wm8994->suspended = true; - - ret = regulator_bulk_disable(wm8994->num_supplies, - wm8994->supplies); - if (ret != 0) { - dev_err(dev, "Failed to disable supplies: %d\n", ret); - return ret; - } - - return 0; -} - -static int wm8994_resume(struct device *dev) -{ - struct wm8994 *wm8994 = dev_get_drvdata(dev); - int ret; - int retry = 0; - - /* We may have lied to the PM core about suspending */ - if (!wm8994->suspended) - return 0; - - ret = regulator_bulk_enable(wm8994->num_supplies, - wm8994->supplies); - if (ret != 0) { - dev_err(dev, "Failed to enable supplies: %d\n", ret); - return ret; - } - - regcache_cache_only(wm8994->regmap, false); - //ret = regcache_sync(wm8994->regmap); - //if (ret != 0) { - // dev_err(dev, "Failed to restore register map: %d\n", ret); - // goto err_enable; - //} - - for (retry = 0; retry < 50; retry++) { - ret = regcache_sync(wm8994->regmap); - if (ret != 0) - dev_err(dev, "Failed to restore register map: %d, retry count: %d\n", ret, retry); - else - break; - msleep(50); - } - if (retry == 50) { - dev_err(dev, "Finally failed to restore register map: %d\n", ret); - goto err_enable; - } - - /* 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; - - return 0; - -err_enable: - regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); - - return ret; -} -#endif - -#ifdef CONFIG_REGULATOR -static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) -{ - struct wm8994_ldo_pdata *ldo_pdata; - - if (!pdata) - return 0; - - ldo_pdata = &pdata->ldo[ldo]; - - if (!ldo_pdata->init_data) - return 0; - - return ldo_pdata->init_data->num_consumer_supplies != 0; -} -#else -static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) -{ - return 0; -} -#endif - -static const __devinitdata struct reg_default wm8994_revc_patch[] = { - { 0x102, 0x3 }, - { 0x56, 0x3 }, - { 0x817, 0x0 }, - { 0x102, 0x0 }, -}; - -static const __devinitdata struct reg_default wm8958_reva_patch[] = { - { 0x102, 0x3 }, - { 0xcb, 0x81 }, - { 0x817, 0x0 }, - { 0x102, 0x0 }, -}; - -static const __devinitdata struct reg_default wm1811_reva_patch[] = { - { 0x102, 0x3 }, - { 0x56, 0x7 }, - { 0x5d, 0x7e }, - { 0x5e, 0x0 }, - { 0x102, 0x0 }, -}; - -/* - * Instantiate the generic non-control parts of the device. - */ -static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) -{ - struct wm8994_pdata *pdata = wm8994->dev->platform_data; - struct regmap_config *regmap_config; - const struct reg_default *regmap_patch = NULL; - const char *devname; - int ret, i, patch_regs; - int pulls = 0; - - dev_set_drvdata(wm8994->dev, wm8994); - - /* Add the on-chip regulators first for bootstrapping */ - ret = mfd_add_devices(wm8994->dev, -1, - wm8994_regulator_devs, - ARRAY_SIZE(wm8994_regulator_devs), - NULL, 0); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to add children: %d\n", ret); - goto err; - } - - switch (wm8994->type) { - case WM1811: - wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies); - break; - case WM8994: - wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); - break; - case WM8958: - wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies); - break; - default: - BUG(); - goto err; - } - - wm8994->supplies = devm_kzalloc(wm8994->dev, - sizeof(struct regulator_bulk_data) * - wm8994->num_supplies, GFP_KERNEL); - if (!wm8994->supplies) { - ret = -ENOMEM; - goto err; - } - - switch (wm8994->type) { - case WM1811: - for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++) - wm8994->supplies[i].supply = wm1811_main_supplies[i]; - break; - case WM8994: - for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) - wm8994->supplies[i].supply = wm8994_main_supplies[i]; - break; - case WM8958: - for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++) - wm8994->supplies[i].supply = wm8958_main_supplies[i]; - break; - default: - BUG(); - goto err; - } - - ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, - wm8994->supplies); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); - goto err; - } - - ret = regulator_bulk_enable(wm8994->num_supplies, - wm8994->supplies); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; - } - - ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET); - if (ret < 0) { - dev_err(wm8994->dev, "Failed to read ID register\n"); - goto err_enable; - } - switch (ret) { - case 0x1811: - devname = "WM1811"; - if (wm8994->type != WM1811) - dev_warn(wm8994->dev, "Device registered as type %d\n", - wm8994->type); - wm8994->type = WM1811; - break; - case 0x8994: - devname = "WM8994"; - if (wm8994->type != WM8994) - dev_warn(wm8994->dev, "Device registered as type %d\n", - wm8994->type); - wm8994->type = WM8994; - break; - case 0x8958: - devname = "WM8958"; - if (wm8994->type != WM8958) - dev_warn(wm8994->dev, "Device registered as type %d\n", - wm8994->type); - wm8994->type = WM8958; - break; - default: - dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", - ret); - ret = -EINVAL; - goto err_enable; - } - - ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION); - if (ret < 0) { - dev_err(wm8994->dev, "Failed to read revision register: %d\n", - ret); - goto err_enable; - } - wm8994->revision = ret; - - switch (wm8994->type) { - case WM8994: - switch (wm8994->revision) { - case 0: - case 1: - dev_warn(wm8994->dev, - "revision %c not fully supported\n", - 'A' + wm8994->revision); - break; - case 2: - case 3: - regmap_patch = wm8994_revc_patch; - patch_regs = ARRAY_SIZE(wm8994_revc_patch); - break; - default: - break; - } - break; - - case WM8958: - switch (wm8994->revision) { - case 0: - regmap_patch = wm8958_reva_patch; - patch_regs = ARRAY_SIZE(wm8958_reva_patch); - break; - default: - break; - } - break; - - case WM1811: - /* Revision C did not change the relevant layer */ - if (wm8994->revision > 1) - wm8994->revision++; - switch (wm8994->revision) { - case 0: - case 1: - case 2: - case 3: - regmap_patch = wm1811_reva_patch; - patch_regs = ARRAY_SIZE(wm1811_reva_patch); - break; - default: - break; - } - break; - - default: - break; - } - - dev_info(wm8994->dev, "%s revision %c\n", devname, - 'A' + wm8994->revision); - - wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, - wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); - - switch (wm8994->type) { - case WM1811: - regmap_config = &wm1811_regmap_config; - break; - case WM8994: - regmap_config = &wm8994_regmap_config; - break; - case WM8958: - regmap_config = &wm8958_regmap_config; - break; - default: - dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type); - return -EINVAL; - } - - ret = regmap_reinit_cache(wm8994->regmap, regmap_config); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to reinit register cache: %d\n", - ret); - return ret; - } - - if (regmap_patch) { - ret = regmap_register_patch(wm8994->regmap, regmap_patch, - patch_regs); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to register patch: %d\n", - ret); - goto err; - } - } - - if (pdata) { - wm8994->irq_base = pdata->irq_base; - wm8994->gpio_base = pdata->gpio_base; - - /* GPIO configuration is only applied if it's non-zero */ - for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { - if (pdata->gpio_defaults[i]) { - wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, - 0xffff, - pdata->gpio_defaults[i]); - } - } - - wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; - - if (pdata->spkmode_pu) - pulls |= WM8994_SPKMODE_PU; - } - - /* Disable unneeded pulls */ - wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, - WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD | - WM8994_SPKMODE_PU | WM8994_CSNADDR_PD, - pulls); - - /* In some system designs where the regulators are not in use, - * we can achieve a small reduction in leakage currents by - * floating LDO outputs. This bit makes no difference if the - * LDOs are enabled, it only affects cases where the LDOs were - * in operation and are then disabled. - */ - for (i = 0; i < WM8994_NUM_LDO_REGS; i++) { - if (wm8994_ldo_in_use(pdata, i)) - wm8994_set_bits(wm8994, WM8994_LDO_1 + i, - WM8994_LDO1_DISCH, WM8994_LDO1_DISCH); - else - wm8994_set_bits(wm8994, WM8994_LDO_1 + i, - WM8994_LDO1_DISCH, 0); - } - - wm8994_irq_init(wm8994); - - ret = mfd_add_devices(wm8994->dev, -1, - wm8994_devs, ARRAY_SIZE(wm8994_devs), - NULL, 0); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to add children: %d\n", ret); - goto err_irq; - } - - pm_runtime_enable(wm8994->dev); - pm_runtime_idle(wm8994->dev); - - return 0; - -err_irq: - wm8994_irq_exit(wm8994); -err_enable: - regulator_bulk_disable(wm8994->num_supplies, - wm8994->supplies); -err_get: - regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); -err: - mfd_remove_devices(wm8994->dev); - return ret; -} - -static __devexit void wm8994_device_exit(struct wm8994 *wm8994) -{ - pm_runtime_disable(wm8994->dev); - mfd_remove_devices(wm8994->dev); - wm8994_irq_exit(wm8994); - regulator_bulk_disable(wm8994->num_supplies, - wm8994->supplies); - regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); -} - -static const struct of_device_id wm8994_of_match[] = { - { .compatible = "wlf,wm1811", }, - { .compatible = "wlf,wm8994", }, - { .compatible = "wlf,wm8958", }, - { } -}; -MODULE_DEVICE_TABLE(of, wm8994_of_match); - -static __devinit int wm8994_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8994 *wm8994; - int ret; - - wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL); - if (wm8994 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm8994); - wm8994->dev = &i2c->dev; - wm8994->irq = i2c->irq; - wm8994->type = id->driver_data; - - wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config); - if (IS_ERR(wm8994->regmap)) { - ret = PTR_ERR(wm8994->regmap); - dev_err(wm8994->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - return wm8994_device_init(wm8994, i2c->irq); -} - -static __devexit int wm8994_i2c_remove(struct i2c_client *i2c) -{ - struct wm8994 *wm8994 = i2c_get_clientdata(i2c); - - wm8994_device_exit(wm8994); - - return 0; -} - -static const struct i2c_device_id wm8994_i2c_id[] = { - { "wm1811", WM1811 }, - { "wm1811a", WM1811 }, - { "wm8994", WM8994 }, - { "wm8958", WM8958 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); - -static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, - NULL); - -static struct i2c_driver wm8994_i2c_driver = { - .driver = { - .name = "wm8994", - .owner = THIS_MODULE, - .pm = &wm8994_pm_ops, - .of_match_table = wm8994_of_match, - }, - .probe = wm8994_i2c_probe, - .remove = __devexit_p(wm8994_i2c_remove), - .id_table = wm8994_i2c_id, -}; - -static int __init wm8994_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&wm8994_i2c_driver); - if (ret != 0) - pr_err("Failed to register wm8994 I2C driver: %d\n", ret); - - return ret; -} -module_init(wm8994_i2c_init); - -static void __exit wm8994_i2c_exit(void) -{ - i2c_del_driver(&wm8994_i2c_driver); -} -module_exit(wm8994_i2c_exit); - -MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/ANDROID_3.4.5/drivers/mfd/wm8994-irq.c b/ANDROID_3.4.5/drivers/mfd/wm8994-irq.c deleted file mode 100644 index 46b20c44..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8994-irq.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * wm8994-irq.c -- Interrupt controller support for Wolfson WM8994 - * - * Copyright 2010 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/mfd/core.h> -#include <linux/interrupt.h> -#include <linux/regmap.h> - -#include <linux/mfd/wm8994/core.h> -#include <linux/mfd/wm8994/registers.h> - -#include <linux/delay.h> - -static struct regmap_irq wm8994_irqs[] = { - [WM8994_IRQ_TEMP_SHUT] = { - .reg_offset = 1, - .mask = WM8994_TEMP_SHUT_EINT, - }, - [WM8994_IRQ_MIC1_DET] = { - .reg_offset = 1, - .mask = WM8994_MIC1_DET_EINT, - }, - [WM8994_IRQ_MIC1_SHRT] = { - .reg_offset = 1, - .mask = WM8994_MIC1_SHRT_EINT, - }, - [WM8994_IRQ_MIC2_DET] = { - .reg_offset = 1, - .mask = WM8994_MIC2_DET_EINT, - }, - [WM8994_IRQ_MIC2_SHRT] = { - .reg_offset = 1, - .mask = WM8994_MIC2_SHRT_EINT, - }, - [WM8994_IRQ_FLL1_LOCK] = { - .reg_offset = 1, - .mask = WM8994_FLL1_LOCK_EINT, - }, - [WM8994_IRQ_FLL2_LOCK] = { - .reg_offset = 1, - .mask = WM8994_FLL2_LOCK_EINT, - }, - [WM8994_IRQ_SRC1_LOCK] = { - .reg_offset = 1, - .mask = WM8994_SRC1_LOCK_EINT, - }, - [WM8994_IRQ_SRC2_LOCK] = { - .reg_offset = 1, - .mask = WM8994_SRC2_LOCK_EINT, - }, - [WM8994_IRQ_AIF1DRC1_SIG_DET] = { - .reg_offset = 1, - .mask = WM8994_AIF1DRC1_SIG_DET, - }, - [WM8994_IRQ_AIF1DRC2_SIG_DET] = { - .reg_offset = 1, - .mask = WM8994_AIF1DRC2_SIG_DET_EINT, - }, - [WM8994_IRQ_AIF2DRC_SIG_DET] = { - .reg_offset = 1, - .mask = WM8994_AIF2DRC_SIG_DET_EINT, - }, - [WM8994_IRQ_FIFOS_ERR] = { - .reg_offset = 1, - .mask = WM8994_FIFOS_ERR_EINT, - }, - [WM8994_IRQ_WSEQ_DONE] = { - .reg_offset = 1, - .mask = WM8994_WSEQ_DONE_EINT, - }, - [WM8994_IRQ_DCS_DONE] = { - .reg_offset = 1, - .mask = WM8994_DCS_DONE_EINT, - }, - [WM8994_IRQ_TEMP_WARN] = { - .reg_offset = 1, - .mask = WM8994_TEMP_WARN_EINT, - }, - [WM8994_IRQ_GPIO(1)] = { - .mask = WM8994_GP1_EINT, - }, - [WM8994_IRQ_GPIO(2)] = { - .mask = WM8994_GP2_EINT, - }, - [WM8994_IRQ_GPIO(3)] = { - .mask = WM8994_GP3_EINT, - }, - [WM8994_IRQ_GPIO(4)] = { - .mask = WM8994_GP4_EINT, - }, - [WM8994_IRQ_GPIO(5)] = { - .mask = WM8994_GP5_EINT, - }, - [WM8994_IRQ_GPIO(6)] = { - .mask = WM8994_GP6_EINT, - }, - [WM8994_IRQ_GPIO(7)] = { - .mask = WM8994_GP7_EINT, - }, - [WM8994_IRQ_GPIO(8)] = { - .mask = WM8994_GP8_EINT, - }, - [WM8994_IRQ_GPIO(9)] = { - .mask = WM8994_GP8_EINT, - }, - [WM8994_IRQ_GPIO(10)] = { - .mask = WM8994_GP10_EINT, - }, - [WM8994_IRQ_GPIO(11)] = { - .mask = WM8994_GP11_EINT, - }, -}; - -static struct regmap_irq_chip wm8994_irq_chip = { - .name = "wm8994", - .irqs = wm8994_irqs, - .num_irqs = ARRAY_SIZE(wm8994_irqs), - - .num_regs = 2, - .status_base = WM8994_INTERRUPT_STATUS_1, - .mask_base = WM8994_INTERRUPT_STATUS_1_MASK, - .ack_base = WM8994_INTERRUPT_STATUS_1, -}; - -int wm8994_irq_init(struct wm8994 *wm8994) -{ - int ret; - - if (!wm8994->irq) { - dev_warn(wm8994->dev, - "No interrupt specified, no interrupts\n"); - wm8994->irq_base = 0; - return 0; - } - - if (!wm8994->irq_base) { - dev_err(wm8994->dev, - "No interrupt base specified, no interrupts\n"); - return 0; - } - - ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - wm8994->irq_base, &wm8994_irq_chip, - &wm8994->irq_data); - if (ret != 0) { - dev_err(wm8994->dev, "Failed to register IRQ chip: %d\n", ret); - return ret; - } - - /* Enable top level interrupt if it was masked */ - wm8994_reg_write(wm8994, WM8994_INTERRUPT_CONTROL, 0); - - return 0; -} - -void wm8994_irq_exit(struct wm8994 *wm8994) -{ - regmap_del_irq_chip(wm8994->irq, wm8994->irq_data); -} diff --git a/ANDROID_3.4.5/drivers/mfd/wm8994-regmap.c b/ANDROID_3.4.5/drivers/mfd/wm8994-regmap.c deleted file mode 100644 index bfd25af6..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8994-regmap.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* - * wm8994-regmap.c -- Register map data for WM8994 series devices - * - * Copyright 2011 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/mfd/wm8994/core.h> -#include <linux/mfd/wm8994/registers.h> -#include <linux/regmap.h> -#include <linux/device.h> - -#include "wm8994.h" - -static struct reg_default wm1811_defaults[] = { - { 0x0001, 0x0000 }, /* R1 - Power Management (1) */ - { 0x0002, 0x6000 }, /* R2 - Power Management (2) */ - { 0x0003, 0x0000 }, /* R3 - Power Management (3) */ - { 0x0004, 0x0000 }, /* R4 - Power Management (4) */ - { 0x0005, 0x0000 }, /* R5 - Power Management (5) */ - { 0x0006, 0x0000 }, /* R6 - Power Management (6) */ - { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */ - { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ - { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ - { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ - { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ - { 0x001C, 0x006D }, /* R28 - Left Output Volume */ - { 0x001D, 0x006D }, /* R29 - Right Output Volume */ - { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */ - { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */ - { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */ - { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */ - { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */ - { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */ - { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */ - { 0x0025, 0x0140 }, /* R37 - ClassD */ - { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */ - { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */ - { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */ - { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */ - { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */ - { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */ - { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */ - { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */ - { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */ - { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */ - { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */ - { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */ - { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */ - { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */ - { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */ - { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */ - { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */ - { 0x0037, 0x0000 }, /* R55 - Additional Control */ - { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */ - { 0x0039, 0x0000 }, /* R57 - AntiPOP (2) */ - { 0x003B, 0x000D }, /* R59 - LDO 1 */ - { 0x003C, 0x0003 }, /* R60 - LDO 2 */ - { 0x003D, 0x0039 }, /* R61 - MICBIAS1 */ - { 0x003E, 0x0039 }, /* R62 - MICBIAS2 */ - { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */ - { 0x004D, 0xAB19 }, /* R77 - Charge Pump (2) */ - { 0x0051, 0x0004 }, /* R81 - Class W (1) */ - { 0x0055, 0x054A }, /* R85 - DC Servo (2) */ - { 0x0059, 0x0000 }, /* R89 - DC Servo (4) */ - { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */ - { 0x00C5, 0x0000 }, /* R197 - Class D Test (5) */ - { 0x00D0, 0x7600 }, /* R208 - Mic Detect 1 */ - { 0x00D1, 0x007F }, /* R209 - Mic Detect 2 */ - { 0x0101, 0x8004 }, /* R257 - Control Interface */ - { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */ - { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */ - { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */ - { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */ - { 0x0208, 0x0000 }, /* R520 - Clocking (1) */ - { 0x0209, 0x0000 }, /* R521 - Clocking (2) */ - { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */ - { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */ - { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */ - { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */ - { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */ - { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */ - { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */ - { 0x0226, 0x0000 }, /* R550 - FLL1 EFS 1 */ - { 0x0227, 0x0006 }, /* R551 - FLL1 EFS 2 */ - { 0x0240, 0x0000 }, /* R576 - FLL2Control (1) */ - { 0x0241, 0x0000 }, /* R577 - FLL2Control (2) */ - { 0x0242, 0x0000 }, /* R578 - FLL2Control (3) */ - { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */ - { 0x0244, 0x0C80 }, /* R580 - FLL2Control (5) */ - { 0x0246, 0x0000 }, /* R582 - FLL2 EFS 1 */ - { 0x0247, 0x0006 }, /* R583 - FLL2 EFS 2 */ - { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */ - { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */ - { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */ - { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */ - { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */ - { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */ - { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */ - { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */ - { 0x0310, 0x4050 }, /* R784 - AIF2 Control (1) */ - { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */ - { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */ - { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */ - { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */ - { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */ - { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */ - { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */ - { 0x0318, 0x0003 }, /* R792 - AIF2TX Control */ - { 0x0320, 0x0040 }, /* R800 - AIF3 Control (1) */ - { 0x0321, 0x0000 }, /* R801 - AIF3 Control (2) */ - { 0x0322, 0x0000 }, /* R802 - AIF3DAC Data */ - { 0x0323, 0x0000 }, /* R803 - AIF3ADC Data */ - { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */ - { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */ - { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */ - { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ - { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ - { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */ - { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */ - { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */ - { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */ - { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */ - { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0530, 0x0068 }, /* R1328 - AIF2 DAC Noise Gate */ - { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */ - { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */ - { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */ - { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */ - { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */ - { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */ - { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */ - { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */ - { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */ - { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */ - { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */ - { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */ - { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */ - { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */ - { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */ - { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */ - { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */ - { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */ - { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */ - { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0594, 0x0000 }, /* R1428 - AIF2 EQ Band 1 C */ - { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x0603, 0x0000 }, /* R1539 - AIF2ADC Mixer Volumes */ - { 0x0604, 0x0000 }, /* R1540 - AIF2ADC Left Mixer Routing */ - { 0x0605, 0x0000 }, /* R1541 - AIF2ADC Right Mixer Routing */ - { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */ - { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */ - { 0x0612, 0x02C0 }, /* R1554 - AIF2TX Left Volume */ - { 0x0613, 0x02C0 }, /* R1555 - AIF2TX Right Volume */ - { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */ - { 0x0620, 0x0002 }, /* R1568 - Oversampling */ - { 0x0621, 0x0000 }, /* R1569 - Sidetone */ - { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */ - { 0x0701, 0xA101 }, /* R1793 - Pull Control (MCLK2) */ - { 0x0702, 0xA101 }, /* R1794 - Pull Control (BCLK2) */ - { 0x0703, 0xA101 }, /* R1795 - Pull Control (DACLRCLK2) */ - { 0x0704, 0xA101 }, /* R1796 - Pull Control (DACDAT2) */ - { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */ - { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */ - { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */ - { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */ - { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */ - { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */ - { 0x0732, 0x0000 }, /* R1842 - Interrupt Raw Status 2 */ - { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */ - { 0x0739, 0xDFEF }, /* R1849 - Interrupt Status 2 Mask */ - { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */ - { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */ -}; - -static struct reg_default wm8994_defaults[] = { - { 0x0001, 0x0000 }, /* R1 - Power Management (1) */ - { 0x0002, 0x6000 }, /* R2 - Power Management (2) */ - { 0x0003, 0x0000 }, /* R3 - Power Management (3) */ - { 0x0004, 0x0000 }, /* R4 - Power Management (4) */ - { 0x0005, 0x0000 }, /* R5 - Power Management (5) */ - { 0x0006, 0x0000 }, /* R6 - Power Management (6) */ - { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */ - { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ - { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ - { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ - { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ - { 0x001C, 0x006D }, /* R28 - Left Output Volume */ - { 0x001D, 0x006D }, /* R29 - Right Output Volume */ - { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */ - { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */ - { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */ - { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */ - { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */ - { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */ - { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */ - { 0x0025, 0x0140 }, /* R37 - ClassD */ - { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */ - { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */ - { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */ - { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */ - { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */ - { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */ - { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */ - { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */ - { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */ - { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */ - { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */ - { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */ - { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */ - { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */ - { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */ - { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */ - { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */ - { 0x0037, 0x0000 }, /* R55 - Additional Control */ - { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */ - { 0x0039, 0x0000 }, /* R57 - AntiPOP (2) */ - { 0x003A, 0x0000 }, /* R58 - MICBIAS */ - { 0x003B, 0x000D }, /* R59 - LDO 1 */ - { 0x003C, 0x0003 }, /* R60 - LDO 2 */ - { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */ - { 0x0051, 0x0004 }, /* R81 - Class W (1) */ - { 0x0055, 0x054A }, /* R85 - DC Servo (2) */ - { 0x0057, 0x0000 }, /* R87 - DC Servo (4) */ - { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */ - { 0x0101, 0x8004 }, /* R257 - Control Interface */ - { 0x0110, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */ - { 0x0111, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ - { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */ - { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */ - { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */ - { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */ - { 0x0208, 0x0000 }, /* R520 - Clocking (1) */ - { 0x0209, 0x0000 }, /* R521 - Clocking (2) */ - { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */ - { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */ - { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */ - { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */ - { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */ - { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */ - { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */ - { 0x0240, 0x0000 }, /* R576 - FLL2 Control (1) */ - { 0x0241, 0x0000 }, /* R577 - FLL2 Control (2) */ - { 0x0242, 0x0000 }, /* R578 - FLL2 Control (3) */ - { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */ - { 0x0244, 0x0C80 }, /* R580 - FLL2 Control (5) */ - { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */ - { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */ - { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */ - { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */ - { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */ - { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */ - { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */ - { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */ - { 0x0310, 0x4050 }, /* R784 - AIF2 Control (1) */ - { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */ - { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */ - { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */ - { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */ - { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */ - { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */ - { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */ - { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x0404, 0x00C0 }, /* R1028 - AIF1 ADC2 Left Volume */ - { 0x0405, 0x00C0 }, /* R1029 - AIF1 ADC2 Right Volume */ - { 0x0406, 0x00C0 }, /* R1030 - AIF1 DAC2 Left Volume */ - { 0x0407, 0x00C0 }, /* R1031 - AIF1 DAC2 Right Volume */ - { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */ - { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */ - { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */ - { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */ - { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */ - { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ - { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ - { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */ - { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */ - { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */ - { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */ - { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */ - { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */ - { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */ - { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */ - { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */ - { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */ - { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */ - { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */ - { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */ - { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */ - { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */ - { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */ - { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */ - { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */ - { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */ - { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */ - { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */ - { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */ - { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */ - { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */ - { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */ - { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */ - { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */ - { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */ - { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x0603, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */ - { 0x0604, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */ - { 0x0605, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */ - { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ - { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */ - { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */ - { 0x0612, 0x02C0 }, /* R1554 - DAC2 Left Volume */ - { 0x0613, 0x02C0 }, /* R1555 - DAC2 Right Volume */ - { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */ - { 0x0620, 0x0002 }, /* R1568 - Oversampling */ - { 0x0621, 0x0000 }, /* R1569 - Sidetone */ - { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */ - { 0x0701, 0xA101 }, /* R1793 - GPIO 2 */ - { 0x0702, 0xA101 }, /* R1794 - GPIO 3 */ - { 0x0703, 0xA101 }, /* R1795 - GPIO 4 */ - { 0x0704, 0xA101 }, /* R1796 - GPIO 5 */ - { 0x0705, 0xA101 }, /* R1797 - GPIO 6 */ - { 0x0706, 0xA101 }, /* R1798 - GPIO 7 */ - { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */ - { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */ - { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */ - { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */ - { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */ - { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */ - { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */ - { 0x0739, 0xFFFF }, /* R1849 - Interrupt Status 2 Mask */ - { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */ - { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */ -}; - -static struct reg_default wm8958_defaults[] = { - { 0x0001, 0x0000 }, /* R1 - Power Management (1) */ - { 0x0002, 0x6000 }, /* R2 - Power Management (2) */ - { 0x0003, 0x0000 }, /* R3 - Power Management (3) */ - { 0x0004, 0x0000 }, /* R4 - Power Management (4) */ - { 0x0005, 0x0000 }, /* R5 - Power Management (5) */ - { 0x0006, 0x0000 }, /* R6 - Power Management (6) */ - { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */ - { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ - { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ - { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ - { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ - { 0x001C, 0x006D }, /* R28 - Left Output Volume */ - { 0x001D, 0x006D }, /* R29 - Right Output Volume */ - { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */ - { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */ - { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */ - { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */ - { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */ - { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */ - { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */ - { 0x0025, 0x0140 }, /* R37 - ClassD */ - { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */ - { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */ - { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */ - { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */ - { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */ - { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */ - { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */ - { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */ - { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */ - { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */ - { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */ - { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */ - { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */ - { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */ - { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */ - { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */ - { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */ - { 0x0037, 0x0000 }, /* R55 - Additional Control */ - { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */ - { 0x0039, 0x0180 }, /* R57 - AntiPOP (2) */ - { 0x003B, 0x000D }, /* R59 - LDO 1 */ - { 0x003C, 0x0005 }, /* R60 - LDO 2 */ - { 0x003D, 0x0039 }, /* R61 - MICBIAS1 */ - { 0x003E, 0x0039 }, /* R62 - MICBIAS2 */ - { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */ - { 0x004D, 0xAB19 }, /* R77 - Charge Pump (2) */ - { 0x0051, 0x0004 }, /* R81 - Class W (1) */ - { 0x0055, 0x054A }, /* R85 - DC Servo (2) */ - { 0x0057, 0x0000 }, /* R87 - DC Servo (4) */ - { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */ - { 0x00C5, 0x0000 }, /* R197 - Class D Test (5) */ - { 0x00D0, 0x5600 }, /* R208 - Mic Detect 1 */ - { 0x00D1, 0x007F }, /* R209 - Mic Detect 2 */ - { 0x0101, 0x8004 }, /* R257 - Control Interface */ - { 0x0110, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */ - { 0x0111, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ - { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */ - { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */ - { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */ - { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */ - { 0x0208, 0x0000 }, /* R520 - Clocking (1) */ - { 0x0209, 0x0000 }, /* R521 - Clocking (2) */ - { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */ - { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */ - { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */ - { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */ - { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */ - { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */ - { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */ - { 0x0226, 0x0000 }, /* R550 - FLL1 EFS 1 */ - { 0x0227, 0x0006 }, /* R551 - FLL1 EFS 2 */ - { 0x0240, 0x0000 }, /* R576 - FLL2Control (1) */ - { 0x0241, 0x0000 }, /* R577 - FLL2Control (2) */ - { 0x0242, 0x0000 }, /* R578 - FLL2Control (3) */ - { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */ - { 0x0244, 0x0C80 }, /* R580 - FLL2Control (5) */ - { 0x0246, 0x0000 }, /* R582 - FLL2 EFS 1 */ - { 0x0247, 0x0006 }, /* R583 - FLL2 EFS 2 */ - { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */ - { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */ - { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */ - { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */ - { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */ - { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */ - { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */ - { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */ - { 0x0310, 0x4053 }, /* R784 - AIF2 Control (1) */ - { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */ - { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */ - { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */ - { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */ - { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */ - { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */ - { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */ - { 0x0320, 0x0040 }, /* R800 - AIF3 Control (1) */ - { 0x0321, 0x0000 }, /* R801 - AIF3 Control (2) */ - { 0x0322, 0x0000 }, /* R802 - AIF3DAC Data */ - { 0x0323, 0x0000 }, /* R803 - AIF3ADC Data */ - { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x0404, 0x00C0 }, /* R1028 - AIF1 ADC2 Left Volume */ - { 0x0405, 0x00C0 }, /* R1029 - AIF1 ADC2 Right Volume */ - { 0x0406, 0x00C0 }, /* R1030 - AIF1 DAC2 Left Volume */ - { 0x0407, 0x00C0 }, /* R1031 - AIF1 DAC2 Right Volume */ - { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */ - { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */ - { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */ - { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */ - { 0x0431, 0x0068 }, /* R1073 - AIF1 DAC2 Noise Gate */ - { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */ - { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */ - { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ - { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ - { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */ - { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */ - { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */ - { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */ - { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */ - { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */ - { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - { 0x04B4, 0x0000 }, /* R1204 - AIF1 DAC2EQ Band 1 C */ - { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */ - { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */ - { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */ - { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */ - { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0530, 0x0068 }, /* R1328 - AIF2 DAC Noise Gate */ - { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */ - { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */ - { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */ - { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */ - { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */ - { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */ - { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */ - { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */ - { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */ - { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */ - { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */ - { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */ - { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */ - { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */ - { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */ - { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */ - { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */ - { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */ - { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */ - { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0594, 0x0000 }, /* R1428 - AIF2 EQ Band 1 C */ - { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x0603, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */ - { 0x0604, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */ - { 0x0605, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */ - { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ - { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */ - { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */ - { 0x0612, 0x02C0 }, /* R1554 - DAC2 Left Volume */ - { 0x0613, 0x02C0 }, /* R1555 - DAC2 Right Volume */ - { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */ - { 0x0620, 0x0002 }, /* R1568 - Oversampling */ - { 0x0621, 0x0000 }, /* R1569 - Sidetone */ - { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */ - { 0x0701, 0xA101 }, /* R1793 - Pull Control (MCLK2) */ - { 0x0702, 0xA101 }, /* R1794 - Pull Control (BCLK2) */ - { 0x0703, 0xA101 }, /* R1795 - Pull Control (DACLRCLK2) */ - { 0x0704, 0xA101 }, /* R1796 - Pull Control (DACDAT2) */ - { 0x0705, 0xA101 }, /* R1797 - GPIO 6 */ - { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */ - { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */ - { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */ - { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */ - { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */ - { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */ - { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */ - { 0x0739, 0xFFEF }, /* R1849 - Interrupt Status 2 Mask */ - { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */ - { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */ - { 0x0900, 0x1C00 }, /* R2304 - DSP2_Program */ - { 0x0901, 0x0000 }, /* R2305 - DSP2_Config */ - { 0x0A0D, 0x0000 }, /* R2573 - DSP2_ExecControl */ - { 0x2400, 0x003F }, /* R9216 - MBC Band 1 K (1) */ - { 0x2401, 0x8BD8 }, /* R9217 - MBC Band 1 K (2) */ - { 0x2402, 0x0032 }, /* R9218 - MBC Band 1 N1 (1) */ - { 0x2403, 0xF52D }, /* R9219 - MBC Band 1 N1 (2) */ - { 0x2404, 0x0065 }, /* R9220 - MBC Band 1 N2 (1) */ - { 0x2405, 0xAC8C }, /* R9221 - MBC Band 1 N2 (2) */ - { 0x2406, 0x006B }, /* R9222 - MBC Band 1 N3 (1) */ - { 0x2407, 0xE087 }, /* R9223 - MBC Band 1 N3 (2) */ - { 0x2408, 0x0072 }, /* R9224 - MBC Band 1 N4 (1) */ - { 0x2409, 0x1483 }, /* R9225 - MBC Band 1 N4 (2) */ - { 0x240A, 0x0072 }, /* R9226 - MBC Band 1 N5 (1) */ - { 0x240B, 0x1483 }, /* R9227 - MBC Band 1 N5 (2) */ - { 0x240C, 0x0043 }, /* R9228 - MBC Band 1 X1 (1) */ - { 0x240D, 0x3525 }, /* R9229 - MBC Band 1 X1 (2) */ - { 0x240E, 0x0006 }, /* R9230 - MBC Band 1 X2 (1) */ - { 0x240F, 0x6A4A }, /* R9231 - MBC Band 1 X2 (2) */ - { 0x2410, 0x0043 }, /* R9232 - MBC Band 1 X3 (1) */ - { 0x2411, 0x6079 }, /* R9233 - MBC Band 1 X3 (2) */ - { 0x2412, 0x000C }, /* R9234 - MBC Band 1 Attack (1) */ - { 0x2413, 0xCCCD }, /* R9235 - MBC Band 1 Attack (2) */ - { 0x2414, 0x0000 }, /* R9236 - MBC Band 1 Decay (1) */ - { 0x2415, 0x0800 }, /* R9237 - MBC Band 1 Decay (2) */ - { 0x2416, 0x003F }, /* R9238 - MBC Band 2 K (1) */ - { 0x2417, 0x8BD8 }, /* R9239 - MBC Band 2 K (2) */ - { 0x2418, 0x0032 }, /* R9240 - MBC Band 2 N1 (1) */ - { 0x2419, 0xF52D }, /* R9241 - MBC Band 2 N1 (2) */ - { 0x241A, 0x0065 }, /* R9242 - MBC Band 2 N2 (1) */ - { 0x241B, 0xAC8C }, /* R9243 - MBC Band 2 N2 (2) */ - { 0x241C, 0x006B }, /* R9244 - MBC Band 2 N3 (1) */ - { 0x241D, 0xE087 }, /* R9245 - MBC Band 2 N3 (2) */ - { 0x241E, 0x0072 }, /* R9246 - MBC Band 2 N4 (1) */ - { 0x241F, 0x1483 }, /* R9247 - MBC Band 2 N4 (2) */ - { 0x2420, 0x0072 }, /* R9248 - MBC Band 2 N5 (1) */ - { 0x2421, 0x1483 }, /* R9249 - MBC Band 2 N5 (2) */ - { 0x2422, 0x0043 }, /* R9250 - MBC Band 2 X1 (1) */ - { 0x2423, 0x3525 }, /* R9251 - MBC Band 2 X1 (2) */ - { 0x2424, 0x0006 }, /* R9252 - MBC Band 2 X2 (1) */ - { 0x2425, 0x6A4A }, /* R9253 - MBC Band 2 X2 (2) */ - { 0x2426, 0x0043 }, /* R9254 - MBC Band 2 X3 (1) */ - { 0x2427, 0x6079 }, /* R9255 - MBC Band 2 X3 (2) */ - { 0x2428, 0x000C }, /* R9256 - MBC Band 2 Attack (1) */ - { 0x2429, 0xCCCD }, /* R9257 - MBC Band 2 Attack (2) */ - { 0x242A, 0x0000 }, /* R9258 - MBC Band 2 Decay (1) */ - { 0x242B, 0x0800 }, /* R9259 - MBC Band 2 Decay (2) */ - { 0x242C, 0x005A }, /* R9260 - MBC_B2_PG2 (1) */ - { 0x242D, 0x7EFA }, /* R9261 - MBC_B2_PG2 (2) */ - { 0x242E, 0x005A }, /* R9262 - MBC_B1_PG2 (1) */ - { 0x242F, 0x7EFA }, /* R9263 - MBC_B1_PG2 (2) */ - { 0x2600, 0x00A7 }, /* R9728 - MBC Crossover (1) */ - { 0x2601, 0x0D1C }, /* R9729 - MBC Crossover (2) */ - { 0x2602, 0x0083 }, /* R9730 - MBC HPF (1) */ - { 0x2603, 0x98AD }, /* R9731 - MBC HPF (2) */ - { 0x2606, 0x0008 }, /* R9734 - MBC LPF (1) */ - { 0x2607, 0xE7A2 }, /* R9735 - MBC LPF (2) */ - { 0x260A, 0x0055 }, /* R9738 - MBC RMS Limit (1) */ - { 0x260B, 0x8C4B }, /* R9739 - MBC RMS Limit (2) */ -}; - -static bool wm1811_readable_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM8994_SOFTWARE_RESET: - case WM8994_POWER_MANAGEMENT_1: - case WM8994_POWER_MANAGEMENT_2: - case WM8994_POWER_MANAGEMENT_3: - case WM8994_POWER_MANAGEMENT_4: - case WM8994_POWER_MANAGEMENT_5: - case WM8994_POWER_MANAGEMENT_6: - case WM8994_INPUT_MIXER_1: - case WM8994_LEFT_LINE_INPUT_1_2_VOLUME: - case WM8994_LEFT_LINE_INPUT_3_4_VOLUME: - case WM8994_RIGHT_LINE_INPUT_1_2_VOLUME: - case WM8994_RIGHT_LINE_INPUT_3_4_VOLUME: - case WM8994_LEFT_OUTPUT_VOLUME: - case WM8994_RIGHT_OUTPUT_VOLUME: - case WM8994_LINE_OUTPUTS_VOLUME: - case WM8994_HPOUT2_VOLUME: - case WM8994_LEFT_OPGA_VOLUME: - case WM8994_RIGHT_OPGA_VOLUME: - case WM8994_SPKMIXL_ATTENUATION: - case WM8994_SPKMIXR_ATTENUATION: - case WM8994_SPKOUT_MIXERS: - case WM8994_CLASSD: - case WM8994_SPEAKER_VOLUME_LEFT: - case WM8994_SPEAKER_VOLUME_RIGHT: - case WM8994_INPUT_MIXER_2: - case WM8994_INPUT_MIXER_3: - case WM8994_INPUT_MIXER_4: - case WM8994_INPUT_MIXER_5: - case WM8994_INPUT_MIXER_6: - case WM8994_OUTPUT_MIXER_1: - case WM8994_OUTPUT_MIXER_2: - case WM8994_OUTPUT_MIXER_3: - case WM8994_OUTPUT_MIXER_4: - case WM8994_OUTPUT_MIXER_5: - case WM8994_OUTPUT_MIXER_6: - case WM8994_HPOUT2_MIXER: - case WM8994_LINE_MIXER_1: - case WM8994_LINE_MIXER_2: - case WM8994_SPEAKER_MIXER: - case WM8994_ADDITIONAL_CONTROL: - case WM8994_ANTIPOP_1: - case WM8994_ANTIPOP_2: - case WM8994_LDO_1: - case WM8994_LDO_2: - case WM8958_MICBIAS1: - case WM8958_MICBIAS2: - case WM8994_CHARGE_PUMP_1: - case WM8958_CHARGE_PUMP_2: - case WM8994_CLASS_W_1: - case WM8994_DC_SERVO_1: - case WM8994_DC_SERVO_2: - case WM8994_DC_SERVO_READBACK: - case WM8994_DC_SERVO_4: - case WM8994_DC_SERVO_4E: - case WM8994_ANALOGUE_HP_1: - case WM8958_MIC_DETECT_1: - case WM8958_MIC_DETECT_2: - case WM8958_MIC_DETECT_3: - case WM8994_CHIP_REVISION: - case WM8994_CONTROL_INTERFACE: - case WM8994_AIF1_CLOCKING_1: - case WM8994_AIF1_CLOCKING_2: - case WM8994_AIF2_CLOCKING_1: - case WM8994_AIF2_CLOCKING_2: - case WM8994_CLOCKING_1: - case WM8994_CLOCKING_2: - case WM8994_AIF1_RATE: - case WM8994_AIF2_RATE: - case WM8994_RATE_STATUS: - case WM8994_FLL1_CONTROL_1: - case WM8994_FLL1_CONTROL_2: - case WM8994_FLL1_CONTROL_3: - case WM8994_FLL1_CONTROL_4: - case WM8994_FLL1_CONTROL_5: - case WM8958_FLL1_EFS_1: - case WM8958_FLL1_EFS_2: - case WM8994_FLL2_CONTROL_1: - case WM8994_FLL2_CONTROL_2: - case WM8994_FLL2_CONTROL_3: - case WM8994_FLL2_CONTROL_4: - case WM8994_FLL2_CONTROL_5: - case WM8958_FLL2_EFS_1: - case WM8958_FLL2_EFS_2: - case WM8994_AIF1_CONTROL_1: - case WM8994_AIF1_CONTROL_2: - case WM8994_AIF1_MASTER_SLAVE: - case WM8994_AIF1_BCLK: - case WM8994_AIF1ADC_LRCLK: - case WM8994_AIF1DAC_LRCLK: - case WM8994_AIF1DAC_DATA: - case WM8994_AIF1ADC_DATA: - case WM8994_AIF2_CONTROL_1: - case WM8994_AIF2_CONTROL_2: - case WM8994_AIF2_MASTER_SLAVE: - case WM8994_AIF2_BCLK: - case WM8994_AIF2ADC_LRCLK: - case WM8994_AIF2DAC_LRCLK: - case WM8994_AIF2DAC_DATA: - case WM8994_AIF2ADC_DATA: - case WM1811_AIF2TX_CONTROL: - case WM8958_AIF3_CONTROL_1: - case WM8958_AIF3_CONTROL_2: - case WM8958_AIF3DAC_DATA: - case WM8958_AIF3ADC_DATA: - case WM8994_AIF1_ADC1_LEFT_VOLUME: - case WM8994_AIF1_ADC1_RIGHT_VOLUME: - case WM8994_AIF1_DAC1_LEFT_VOLUME: - case WM8994_AIF1_DAC1_RIGHT_VOLUME: - case WM8994_AIF1_ADC1_FILTERS: - case WM8994_AIF1_DAC1_FILTERS_1: - case WM8994_AIF1_DAC1_FILTERS_2: - case WM8958_AIF1_DAC1_NOISE_GATE: - case WM8994_AIF1_DRC1_1: - case WM8994_AIF1_DRC1_2: - case WM8994_AIF1_DRC1_3: - case WM8994_AIF1_DRC1_4: - case WM8994_AIF1_DRC1_5: - case WM8994_AIF1_DAC1_EQ_GAINS_1: - case WM8994_AIF1_DAC1_EQ_GAINS_2: - case WM8994_AIF1_DAC1_EQ_BAND_1_A: - case WM8994_AIF1_DAC1_EQ_BAND_1_B: - case WM8994_AIF1_DAC1_EQ_BAND_1_PG: - case WM8994_AIF1_DAC1_EQ_BAND_2_A: - case WM8994_AIF1_DAC1_EQ_BAND_2_B: - case WM8994_AIF1_DAC1_EQ_BAND_2_C: - case WM8994_AIF1_DAC1_EQ_BAND_2_PG: - case WM8994_AIF1_DAC1_EQ_BAND_3_A: - case WM8994_AIF1_DAC1_EQ_BAND_3_B: - case WM8994_AIF1_DAC1_EQ_BAND_3_C: - case WM8994_AIF1_DAC1_EQ_BAND_3_PG: - case WM8994_AIF1_DAC1_EQ_BAND_4_A: - case WM8994_AIF1_DAC1_EQ_BAND_4_B: - case WM8994_AIF1_DAC1_EQ_BAND_4_C: - case WM8994_AIF1_DAC1_EQ_BAND_4_PG: - case WM8994_AIF1_DAC1_EQ_BAND_5_A: - case WM8994_AIF1_DAC1_EQ_BAND_5_B: - case WM8994_AIF1_DAC1_EQ_BAND_5_PG: - case WM8994_AIF1_DAC1_EQ_BAND_1_C: - case WM8994_AIF2_ADC_LEFT_VOLUME: - case WM8994_AIF2_ADC_RIGHT_VOLUME: - case WM8994_AIF2_DAC_LEFT_VOLUME: - case WM8994_AIF2_DAC_RIGHT_VOLUME: - case WM8994_AIF2_ADC_FILTERS: - case WM8994_AIF2_DAC_FILTERS_1: - case WM8994_AIF2_DAC_FILTERS_2: - case WM8958_AIF2_DAC_NOISE_GATE: - case WM8994_AIF2_DRC_1: - case WM8994_AIF2_DRC_2: - case WM8994_AIF2_DRC_3: - case WM8994_AIF2_DRC_4: - case WM8994_AIF2_DRC_5: - case WM8994_AIF2_EQ_GAINS_1: - case WM8994_AIF2_EQ_GAINS_2: - case WM8994_AIF2_EQ_BAND_1_A: - case WM8994_AIF2_EQ_BAND_1_B: - case WM8994_AIF2_EQ_BAND_1_PG: - case WM8994_AIF2_EQ_BAND_2_A: - case WM8994_AIF2_EQ_BAND_2_B: - case WM8994_AIF2_EQ_BAND_2_C: - case WM8994_AIF2_EQ_BAND_2_PG: - case WM8994_AIF2_EQ_BAND_3_A: - case WM8994_AIF2_EQ_BAND_3_B: - case WM8994_AIF2_EQ_BAND_3_C: - case WM8994_AIF2_EQ_BAND_3_PG: - case WM8994_AIF2_EQ_BAND_4_A: - case WM8994_AIF2_EQ_BAND_4_B: - case WM8994_AIF2_EQ_BAND_4_C: - case WM8994_AIF2_EQ_BAND_4_PG: - case WM8994_AIF2_EQ_BAND_5_A: - case WM8994_AIF2_EQ_BAND_5_B: - case WM8994_AIF2_EQ_BAND_5_PG: - case WM8994_AIF2_EQ_BAND_1_C: - case WM8994_DAC1_MIXER_VOLUMES: - case WM8994_DAC1_LEFT_MIXER_ROUTING: - case WM8994_DAC1_RIGHT_MIXER_ROUTING: - case WM8994_DAC2_MIXER_VOLUMES: - case WM8994_DAC2_LEFT_MIXER_ROUTING: - case WM8994_DAC2_RIGHT_MIXER_ROUTING: - case WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING: - case WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING: - case WM8994_DAC1_LEFT_VOLUME: - case WM8994_DAC1_RIGHT_VOLUME: - case WM8994_DAC2_LEFT_VOLUME: - case WM8994_DAC2_RIGHT_VOLUME: - case WM8994_DAC_SOFTMUTE: - case WM8994_OVERSAMPLING: - case WM8994_SIDETONE: - case WM8994_GPIO_1: - case WM8994_GPIO_2: - case WM8994_GPIO_3: - case WM8994_GPIO_4: - case WM8994_GPIO_5: - case WM8994_GPIO_6: - case WM8994_GPIO_8: - case WM8994_GPIO_9: - case WM8994_GPIO_10: - case WM8994_GPIO_11: - case WM8994_PULL_CONTROL_1: - case WM8994_PULL_CONTROL_2: - case WM8994_INTERRUPT_STATUS_1: - case WM8994_INTERRUPT_STATUS_2: - case WM8994_INTERRUPT_RAW_STATUS_2: - case WM8994_INTERRUPT_STATUS_1_MASK: - case WM8994_INTERRUPT_STATUS_2_MASK: - case WM8994_INTERRUPT_CONTROL: - case WM8994_IRQ_DEBOUNCE: - return true; - default: - return false; - } -} - -static bool wm8994_readable_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM8994_DC_SERVO_READBACK: - case WM8994_MICBIAS: - case WM8994_WRITE_SEQUENCER_CTRL_1: - case WM8994_WRITE_SEQUENCER_CTRL_2: - case WM8994_AIF1_ADC2_LEFT_VOLUME: - case WM8994_AIF1_ADC2_RIGHT_VOLUME: - case WM8994_AIF1_DAC2_LEFT_VOLUME: - case WM8994_AIF1_DAC2_RIGHT_VOLUME: - case WM8994_AIF1_ADC2_FILTERS: - case WM8994_AIF1_DAC2_FILTERS_1: - case WM8994_AIF1_DAC2_FILTERS_2: - case WM8958_AIF1_DAC2_NOISE_GATE: - case WM8994_AIF1_DRC2_1: - case WM8994_AIF1_DRC2_2: - case WM8994_AIF1_DRC2_3: - case WM8994_AIF1_DRC2_4: - case WM8994_AIF1_DRC2_5: - case WM8994_AIF1_DAC2_EQ_GAINS_1: - case WM8994_AIF1_DAC2_EQ_GAINS_2: - case WM8994_AIF1_DAC2_EQ_BAND_1_A: - case WM8994_AIF1_DAC2_EQ_BAND_1_B: - case WM8994_AIF1_DAC2_EQ_BAND_1_PG: - case WM8994_AIF1_DAC2_EQ_BAND_2_A: - case WM8994_AIF1_DAC2_EQ_BAND_2_B: - case WM8994_AIF1_DAC2_EQ_BAND_2_C: - case WM8994_AIF1_DAC2_EQ_BAND_2_PG: - case WM8994_AIF1_DAC2_EQ_BAND_3_A: - case WM8994_AIF1_DAC2_EQ_BAND_3_B: - case WM8994_AIF1_DAC2_EQ_BAND_3_C: - case WM8994_AIF1_DAC2_EQ_BAND_3_PG: - case WM8994_AIF1_DAC2_EQ_BAND_4_A: - case WM8994_AIF1_DAC2_EQ_BAND_4_B: - case WM8994_AIF1_DAC2_EQ_BAND_4_C: - case WM8994_AIF1_DAC2_EQ_BAND_4_PG: - case WM8994_AIF1_DAC2_EQ_BAND_5_A: - case WM8994_AIF1_DAC2_EQ_BAND_5_B: - case WM8994_AIF1_DAC2_EQ_BAND_5_PG: - case WM8994_AIF1_DAC2_EQ_BAND_1_C: - case WM8994_DAC2_MIXER_VOLUMES: - case WM8994_DAC2_LEFT_MIXER_ROUTING: - case WM8994_DAC2_RIGHT_MIXER_ROUTING: - case WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING: - case WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING: - case WM8994_DAC2_LEFT_VOLUME: - case WM8994_DAC2_RIGHT_VOLUME: - return true; - default: - return wm1811_readable_register(dev, reg); - } -} - -static bool wm8958_readable_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM8958_DSP2_PROGRAM: - case WM8958_DSP2_CONFIG: - case WM8958_DSP2_MAGICNUM: - case WM8958_DSP2_RELEASEYEAR: - case WM8958_DSP2_RELEASEMONTHDAY: - case WM8958_DSP2_RELEASETIME: - case WM8958_DSP2_VERMAJMIN: - case WM8958_DSP2_VERBUILD: - case WM8958_DSP2_TESTREG: - case WM8958_DSP2_XORREG: - case WM8958_DSP2_SHIFTMAXX: - case WM8958_DSP2_SHIFTMAXY: - case WM8958_DSP2_SHIFTMAXZ: - case WM8958_DSP2_SHIFTMAXEXTLO: - case WM8958_DSP2_AESSELECT: - case WM8958_DSP2_EXECCONTROL: - case WM8958_DSP2_SAMPLEBREAK: - case WM8958_DSP2_COUNTBREAK: - case WM8958_DSP2_INTSTATUS: - case WM8958_DSP2_EVENTSTATUS: - case WM8958_DSP2_INTMASK: - case WM8958_DSP2_CONFIGDWIDTH: - case WM8958_DSP2_CONFIGINSTR: - case WM8958_DSP2_CONFIGDMEM: - case WM8958_DSP2_CONFIGDELAYS: - case WM8958_DSP2_CONFIGNUMIO: - case WM8958_DSP2_CONFIGEXTDEPTH: - case WM8958_DSP2_CONFIGMULTIPLIER: - case WM8958_DSP2_CONFIGCTRLDWIDTH: - case WM8958_DSP2_CONFIGPIPELINE: - case WM8958_DSP2_SHIFTMAXEXTHI: - case WM8958_DSP2_SWVERSIONREG: - case WM8958_DSP2_CONFIGXMEM: - case WM8958_DSP2_CONFIGYMEM: - case WM8958_DSP2_CONFIGZMEM: - case WM8958_FW_BUILD_1: - case WM8958_FW_BUILD_0: - case WM8958_FW_ID_1: - case WM8958_FW_ID_0: - case WM8958_FW_MAJOR_1: - case WM8958_FW_MAJOR_0: - case WM8958_FW_MINOR_1: - case WM8958_FW_MINOR_0: - case WM8958_FW_PATCH_1: - case WM8958_FW_PATCH_0: - case WM8958_MBC_BAND_1_K_1: - case WM8958_MBC_BAND_1_K_2: - case WM8958_MBC_BAND_1_N1_1: - case WM8958_MBC_BAND_1_N1_2: - case WM8958_MBC_BAND_1_N2_1: - case WM8958_MBC_BAND_1_N2_2: - case WM8958_MBC_BAND_1_N3_1: - case WM8958_MBC_BAND_1_N3_2: - case WM8958_MBC_BAND_1_N4_1: - case WM8958_MBC_BAND_1_N4_2: - case WM8958_MBC_BAND_1_N5_1: - case WM8958_MBC_BAND_1_N5_2: - case WM8958_MBC_BAND_1_X1_1: - case WM8958_MBC_BAND_1_X1_2: - case WM8958_MBC_BAND_1_X2_1: - case WM8958_MBC_BAND_1_X2_2: - case WM8958_MBC_BAND_1_X3_1: - case WM8958_MBC_BAND_1_X3_2: - case WM8958_MBC_BAND_1_ATTACK_1: - case WM8958_MBC_BAND_1_ATTACK_2: - case WM8958_MBC_BAND_1_DECAY_1: - case WM8958_MBC_BAND_1_DECAY_2: - case WM8958_MBC_BAND_2_K_1: - case WM8958_MBC_BAND_2_K_2: - case WM8958_MBC_BAND_2_N1_1: - case WM8958_MBC_BAND_2_N1_2: - case WM8958_MBC_BAND_2_N2_1: - case WM8958_MBC_BAND_2_N2_2: - case WM8958_MBC_BAND_2_N3_1: - case WM8958_MBC_BAND_2_N3_2: - case WM8958_MBC_BAND_2_N4_1: - case WM8958_MBC_BAND_2_N4_2: - case WM8958_MBC_BAND_2_N5_1: - case WM8958_MBC_BAND_2_N5_2: - case WM8958_MBC_BAND_2_X1_1: - case WM8958_MBC_BAND_2_X1_2: - case WM8958_MBC_BAND_2_X2_1: - case WM8958_MBC_BAND_2_X2_2: - case WM8958_MBC_BAND_2_X3_1: - case WM8958_MBC_BAND_2_X3_2: - case WM8958_MBC_BAND_2_ATTACK_1: - case WM8958_MBC_BAND_2_ATTACK_2: - case WM8958_MBC_BAND_2_DECAY_1: - case WM8958_MBC_BAND_2_DECAY_2: - case WM8958_MBC_B2_PG2_1: - case WM8958_MBC_B2_PG2_2: - case WM8958_MBC_B1_PG2_1: - case WM8958_MBC_B1_PG2_2: - case WM8958_MBC_CROSSOVER_1: - case WM8958_MBC_CROSSOVER_2: - case WM8958_MBC_HPF_1: - case WM8958_MBC_HPF_2: - case WM8958_MBC_LPF_1: - case WM8958_MBC_LPF_2: - case WM8958_MBC_RMS_LIMIT_1: - case WM8958_MBC_RMS_LIMIT_2: - return true; - default: - return wm8994_readable_register(dev, reg); - } -} - -static bool wm8994_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM8994_SOFTWARE_RESET: - case WM8994_DC_SERVO_1: - case WM8994_DC_SERVO_READBACK: - case WM8994_RATE_STATUS: - case WM8958_MIC_DETECT_3: - case WM8994_DC_SERVO_4E: - case WM8994_CHIP_REVISION: - case WM8994_INTERRUPT_STATUS_1: - case WM8994_INTERRUPT_STATUS_2: - return true; - default: - return false; - } -} - -static bool wm1811_volatile_register(struct device *dev, unsigned int reg) -{ - struct wm8994 *wm8994 = dev_get_drvdata(dev); - - switch (reg) { - case WM8994_GPIO_6: - if (wm8994->revision > 1) - return true; - else - return false; - default: - return wm8994_volatile_register(dev, reg); - } -} - -static bool wm8958_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WM8958_DSP2_MAGICNUM: - case WM8958_DSP2_RELEASEYEAR: - case WM8958_DSP2_RELEASEMONTHDAY: - case WM8958_DSP2_RELEASETIME: - case WM8958_DSP2_VERMAJMIN: - case WM8958_DSP2_VERBUILD: - case WM8958_DSP2_EXECCONTROL: - case WM8958_DSP2_SWVERSIONREG: - case WM8958_DSP2_CONFIGXMEM: - case WM8958_DSP2_CONFIGYMEM: - case WM8958_DSP2_CONFIGZMEM: - case WM8958_FW_BUILD_1: - case WM8958_FW_BUILD_0: - case WM8958_FW_ID_1: - case WM8958_FW_ID_0: - case WM8958_FW_MAJOR_1: - case WM8958_FW_MAJOR_0: - case WM8958_FW_MINOR_1: - case WM8958_FW_MINOR_0: - case WM8958_FW_PATCH_1: - case WM8958_FW_PATCH_0: - return true; - default: - return wm8994_volatile_register(dev, reg); - } -} - -struct regmap_config wm1811_regmap_config = { - .reg_bits = 16, - .val_bits = 16, - - .cache_type = REGCACHE_RBTREE, - - .reg_defaults = wm1811_defaults, - .num_reg_defaults = ARRAY_SIZE(wm1811_defaults), - - .max_register = WM8994_MAX_REGISTER, - .volatile_reg = wm1811_volatile_register, - .readable_reg = wm1811_readable_register, -}; - -struct regmap_config wm8994_regmap_config = { - .reg_bits = 16, - .val_bits = 16, - - .cache_type = REGCACHE_RBTREE, - - .reg_defaults = wm8994_defaults, - .num_reg_defaults = ARRAY_SIZE(wm8994_defaults), - - .max_register = WM8994_MAX_REGISTER, - .volatile_reg = wm8994_volatile_register, - .readable_reg = wm8994_readable_register, -}; - -struct regmap_config wm8958_regmap_config = { - .reg_bits = 16, - .val_bits = 16, - - .cache_type = REGCACHE_RBTREE, - - .reg_defaults = wm8958_defaults, - .num_reg_defaults = ARRAY_SIZE(wm8958_defaults), - - .max_register = WM8994_MAX_REGISTER, - .volatile_reg = wm8958_volatile_register, - .readable_reg = wm8958_readable_register, -}; - -struct regmap_config wm8994_base_regmap_config = { - .reg_bits = 16, - .val_bits = 16, -}; diff --git a/ANDROID_3.4.5/drivers/mfd/wm8994.h b/ANDROID_3.4.5/drivers/mfd/wm8994.h deleted file mode 100644 index 6f39a84e..00000000 --- a/ANDROID_3.4.5/drivers/mfd/wm8994.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * wm8994.h -- WM8994 MFD internals - * - * Copyright 2011 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#ifndef __MFD_WM8994_H__ -#define __MFD_WM8994_H__ - -#include <linux/regmap.h> - -extern struct regmap_config wm1811_regmap_config; -extern struct regmap_config wm8994_regmap_config; -extern struct regmap_config wm8958_regmap_config; -extern struct regmap_config wm8994_base_regmap_config; - -#endif |