diff options
50 files changed, 1358 insertions, 767 deletions
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c index e606d1bdd3c3..d660ebd497e4 100644 --- a/drivers/gpu/ion/ion.c +++ b/drivers/gpu/ion/ion.c @@ -1070,7 +1070,7 @@ static const struct file_operations ion_fops = { }; static size_t ion_debug_heap_total(struct ion_client *client, - enum ion_heap_type type) + enum ion_heap_type type, const char *name) { size_t size = 0; struct rb_node *n; @@ -1080,8 +1080,14 @@ static size_t ion_debug_heap_total(struct ion_client *client, struct ion_handle *handle = rb_entry(n, struct ion_handle, node); - if (handle->buffer->heap->type == type) - size += handle->buffer->size; + if (handle->buffer->heap->type == type) { + if (handle->buffer->heap->name) { + if (!strcmp(handle->buffer->heap->name, name)) + size += handle->buffer->size; + } else { + size += handle->buffer->size; + } + } } mutex_unlock(&client->lock); return size; @@ -1098,7 +1104,7 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) struct ion_client *client = rb_entry(n, struct ion_client, node); char task_comm[TASK_COMM_LEN]; - size_t size = ion_debug_heap_total(client, heap->type); + size_t size = ion_debug_heap_total(client, heap->type, heap->name); if (!size) continue; @@ -1110,7 +1116,7 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) for (n = rb_first(&dev->kernel_clients); n; n = rb_next(n)) { struct ion_client *client = rb_entry(n, struct ion_client, node); - size_t size = ion_debug_heap_total(client, heap->type); + size_t size = ion_debug_heap_total(client, heap->type, heap->name); if (!size) continue; seq_printf(s, "%16.s %16u %16u\n", client->name, client->pid, diff --git a/drivers/gpu/ion/mxc/mxc_ion.c b/drivers/gpu/ion/mxc/mxc_ion.c index 82a2d082637b..5619621f0dcf 100644 --- a/drivers/gpu/ion/mxc/mxc_ion.c +++ b/drivers/gpu/ion/mxc/mxc_ion.c @@ -49,6 +49,7 @@ int mxc_ion_probe(struct platform_device *pdev) heaps[i] = ion_heap_create(heap_data); if (IS_ERR_OR_NULL(heaps[i])) { err = PTR_ERR(heaps[i]); + heaps[i] = NULL; goto err; } ion_device_add_heap(idev, heaps[i]); diff --git a/drivers/hwmon/da9052-adc.c b/drivers/hwmon/da9052-adc.c index 6803fc2ccea3..3260eb5f4359 100755 --- a/drivers/hwmon/da9052-adc.c +++ b/drivers/hwmon/da9052-adc.c @@ -2,6 +2,7 @@ * da9052-adc.c -- ADC Driver for Dialog DA9052 * * Copyright(c) 2009 Dialog Semiconductor Ltd. + * Copyright (C) 2012 Freescale Semiconductor, Inc. * * Author: Dialog Semiconductor Ltd <dchen@diasemi.com> * @@ -39,6 +40,15 @@ static const char *input_names[] = { [DA9052_ADC_VBBAT] = "BACK-UP BATTERY TEMP", }; +static struct da9052 *da9052_local; + +int da9052_adc_read(unsigned char channel) +{ + if (da9052_local != NULL) + return da9052_manual_read(da9052_local, channel); + return -1; +} +EXPORT_SYMBOL(da9052_adc_read); int da9052_manual_read(struct da9052 *da9052, unsigned char channel) @@ -591,6 +601,7 @@ static int __init da9052_adc_probe(struct platform_device *pdev) /* Initialize mutex required for ADC Manual read */ mutex_init(&priv->da9052->manconv_lock); + da9052_local = priv->da9052; return 0; out_err_create2: diff --git a/drivers/hwmon/imx_ahci_hwmon.c b/drivers/hwmon/imx_ahci_hwmon.c index 073a2d1697dc..030c455798b8 100644 --- a/drivers/hwmon/imx_ahci_hwmon.c +++ b/drivers/hwmon/imx_ahci_hwmon.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. 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 @@ -57,7 +57,7 @@ static ssize_t imx_ahci_hwmon_temp_show(struct device *dev, { void __iomem *mmio; u32 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, adc_out_reg; - u32 str1, str2, str3, str4, read_sum, index; + u32 str1, str2, str3, str4, read_sum, index, port_phy_ctl; int m1, m2, a, temp, ret; struct clk *sata_clk, *sata_ref_clk; struct imx_ahci_hwmon *hwmon; @@ -89,6 +89,11 @@ static ssize_t imx_ahci_hwmon_temp_show(struct device *dev, return -1; } + /* Disable PDDQ mode if it is enabled */ + port_phy_ctl = readl(mmio + PORT_PHY_CTL); + if (port_phy_ctl & PORT_PHY_CTL_PDDQ_LOC) + writel(port_phy_ctl & ~PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); + /* check rd-wr to reg */ read_sum = 0; sata_phy_cr_addr(SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT, mmio); @@ -229,6 +234,9 @@ static ssize_t imx_ahci_hwmon_temp_show(struct device *dev, a = (m2 - m1) / (m2 / 1000); temp = ((((-559) * a) / 1000) * a) / 1000 + (1379) * a / 1000 + (-458); + /* Set the Port Phy ctl back */ + writel(port_phy_ctl, mmio + PORT_PHY_CTL); + iounmap(mmio); /* Release the clocks */ diff --git a/drivers/hwmon/mag3110.c b/drivers/hwmon/mag3110.c index 55f2114869cd..f17212553355 100755 --- a/drivers/hwmon/mag3110.c +++ b/drivers/hwmon/mag3110.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Freescale Semiconductor, Inc. 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 @@ -40,11 +40,12 @@ #define MAG3110_AC_OFFSET 0 #define MAG3110_DR_MODE_MASK (0x7 << 5) #define MAG3110_DR_MODE_OFFSET 5 -#define MAG3110_IRQ_USED 0 +#define MAG3110_IRQ_USED 1 -#define POLL_INTERVAL_MAX 500 -#define POLL_INTERVAL 100 -#define INT_TIMEOUT 1000 +#define POLL_INTERVAL_MIN 100 +#define POLL_INTERVAL_MAX 1000 +#define POLL_INTERVAL 500 +#define INT_TIMEOUT 1000 /* register enum for mag3110 registers */ enum { MAG3110_DR_STATUS = 0x00, @@ -83,15 +84,16 @@ struct mag3110_data { int position; }; static short MAGHAL[8][3][3] = { - { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} }, - { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }, - { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} }, - { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} }, - - { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} }, - { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} }, - { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} }, - { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} }, + {{ 0, 1, 0}, {-1, 0, 0}, {0, 0, 1} }, + {{ 1, 0, 0}, { 0, 1, 0}, {0, 0, 1} }, + {{ 0, -1, 0}, { 1, 0, 0}, {0, 0, 1} }, + {{-1, 0, 0}, { 0, -1, 0}, {0, 0, 1} }, + + {{ 0, 1, 0}, { 1, 0, 0}, {0, 0, -1} }, + {{ 1, 0, 0}, { 0, -1, 0}, {0, 0, -1} }, + {{ 0, -1, 0}, {-1, 0, 0}, {0, 0, -1} }, + {{-1, 0, 0}, { 0, 1, 0}, {0, 0, -1} }, + }; static struct mag3110_data *mag3110_pdata; @@ -106,9 +108,11 @@ static int mag3110_adjust_position(short *x, short *y, short *z) int position = mag3110_pdata->position; if (position < 0 || position > 7) position = 0; + rawdata[0] = *x; rawdata[1] = *y; rawdata[2] = *z; + for (i = 0; i < 3; i++) { data[i] = 0; for (j = 0; j < 3; j++) @@ -142,9 +146,10 @@ static int mag3110_write_reg(struct i2c_client *client, u8 reg, char value) * This function do multiple mag3110 registers read. */ static int mag3110_read_block_data(struct i2c_client *client, u8 reg, - int count, u8 *addr) + int count, u8 *addr) { - if (i2c_smbus_read_i2c_block_data(client, reg, count, addr) < count) { + if (i2c_smbus_read_i2c_block_data + (client, reg, count, addr) < count) { dev_err(&client->dev, "i2c block read failed\n"); return -1; } @@ -172,24 +177,27 @@ static int mag3110_init_client(struct i2c_client *client) } /*************************************************************** -* -* read sensor data from mag3110 -* -***************************************************************/ + * + * read sensor data from mag3110 + * + ***************************************************************/ static int mag3110_read_data(short *x, short *y, short *z) { struct mag3110_data *data; - int retry = 3; u8 tmp_data[MAG3110_XYZ_DATA_LEN]; +#if !MAG3110_IRQ_USED + int retry = 3; int result; +#endif + if (!mag3110_pdata || mag3110_pdata->active == MAG_STANDBY) return -EINVAL; data = mag3110_pdata; #if MAG3110_IRQ_USED if (!wait_event_interruptible_timeout - (data->waitq, data->data_ready != 0, - msecs_to_jiffies(INT_TIMEOUT))) { + (data->waitq, data->data_ready != 0, + msecs_to_jiffies(INT_TIMEOUT))) { dev_dbg(&data->client->dev, "interrupt not received\n"); return -ETIME; } @@ -197,11 +205,12 @@ static int mag3110_read_data(short *x, short *y, short *z) do { msleep(1); result = i2c_smbus_read_byte_data(data->client, - MAG3110_DR_STATUS); + MAG3110_DR_STATUS); retry--; } while (!(result & MAG3110_STATUS_ZYXDR) && retry > 0); /* Clear data_ready flag after data is read out */ if (retry == 0) { + printk(KERN_DEBUG "magd wait data ready timeout....\n"); return -EINVAL; } #endif @@ -209,8 +218,7 @@ static int mag3110_read_data(short *x, short *y, short *z) data->data_ready = 0; if (mag3110_read_block_data(data->client, - MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN, - tmp_data) < 0) + MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN, tmp_data) < 0) return -1; *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1]; @@ -253,7 +261,7 @@ static irqreturn_t mag3110_irq_handler(int irq, void *dev_id) } #endif static ssize_t mag3110_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct i2c_client *client; int val; @@ -266,8 +274,8 @@ static ssize_t mag3110_enable_show(struct device *dev, } static ssize_t mag3110_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client; int reg, ret, enable; @@ -277,7 +285,7 @@ static ssize_t mag3110_enable_store(struct device *dev, mutex_lock(&mag3110_lock); client = mag3110_pdata->client; reg = mag3110_read_reg(client, MAG3110_CTRL_REG1); - if (enable && mag3110_pdata->active == MAG_STANDBY) { + if (enable && mag3110_pdata->active == MAG_STANDBY) { reg |= MAG3110_AC_MASK; ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg); if (!ret) @@ -293,33 +301,33 @@ static ssize_t mag3110_enable_store(struct device *dev, msleep(100); /* Read out MSB data to clear interrupt flag automatically */ mag3110_read_block_data(client, MAG3110_OUT_X_MSB, - MAG3110_XYZ_DATA_LEN, tmp_data); + MAG3110_XYZ_DATA_LEN, tmp_data); } mutex_unlock(&mag3110_lock); return count; } static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, - mag3110_enable_show, mag3110_enable_store); + mag3110_enable_show, mag3110_enable_store); static ssize_t mag3110_dr_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct i2c_client *client; int val; client = mag3110_pdata->client; val = (mag3110_read_reg(client, MAG3110_CTRL_REG1) - & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET; + & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET; return sprintf(buf, "%d\n", val); } static ssize_t mag3110_dr_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { - struct i2c_client *client; + struct i2c_client *client ; int reg, ret; unsigned long val; @@ -329,7 +337,7 @@ static ssize_t mag3110_dr_mode_store(struct device *dev, client = mag3110_pdata->client; reg = mag3110_read_reg(client, MAG3110_CTRL_REG1) & - ~MAG3110_DR_MODE_MASK; + ~MAG3110_DR_MODE_MASK; reg |= (val << MAG3110_DR_MODE_OFFSET); /* MAG3110_CTRL_REG1 bit 5-7: data rate mode */ ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg); @@ -340,10 +348,10 @@ static ssize_t mag3110_dr_mode_store(struct device *dev, } static DEVICE_ATTR(dr_mode, S_IWUSR | S_IRUGO, - mag3110_dr_mode_show, mag3110_dr_mode_store); + mag3110_dr_mode_show, mag3110_dr_mode_store); static ssize_t mag3110_position_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { int val; mutex_lock(&mag3110_lock); @@ -353,8 +361,8 @@ static ssize_t mag3110_position_show(struct device *dev, } static ssize_t mag3110_position_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { int position; position = simple_strtoul(buf, NULL, 10); @@ -365,7 +373,7 @@ static ssize_t mag3110_position_store(struct device *dev, } static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, - mag3110_position_show, mag3110_position_store); + mag3110_position_show, mag3110_position_store); static struct attribute *mag3110_attributes[] = { &dev_attr_enable.attr, @@ -379,7 +387,7 @@ static const struct attribute_group mag3110_attr_group = { }; static int __devinit mag3110_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct i2c_adapter *adapter; struct input_dev *idev; @@ -388,9 +396,9 @@ static int __devinit mag3110_probe(struct i2c_client *client, adapter = to_i2c_adapter(client->dev.parent); if (!i2c_check_functionality(adapter, - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; dev_info(&client->dev, "check mag3110 chip ID\n"); @@ -398,8 +406,8 @@ static int __devinit mag3110_probe(struct i2c_client *client, if (MAG3110_ID != ret) { dev_err(&client->dev, - "read chip ID 0x%x is not equal to 0x%x!\n", ret, - MAG3110_ID); + "read chip ID 0x%x is not equal to 0x%x!\n", + ret, MAG3110_ID); return -EINVAL; } data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL); @@ -426,6 +434,7 @@ static int __devinit mag3110_probe(struct i2c_client *client, } data->poll_dev->poll = mag3110_dev_poll; data->poll_dev->poll_interval = POLL_INTERVAL; + data->poll_dev->poll_interval_min = POLL_INTERVAL_MIN; data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX; idev = data->poll_dev->input; idev->name = MAG3110_DRV_NAME; @@ -450,10 +459,10 @@ static int __devinit mag3110_probe(struct i2c_client *client, /* set irq type to edge rising */ #if MAG3110_IRQ_USED ret = request_irq(client->irq, mag3110_irq_handler, - IRQF_TRIGGER_RISING, client->dev.driver->name, idev); + IRQF_TRIGGER_RISING, client->dev.driver->name, idev); if (ret < 0) { dev_err(&client->dev, "failed to register irq %d!\n", - client->irq); + client->irq); goto error_rm_dev_sysfs; } #endif @@ -488,7 +497,7 @@ static int __devexit mag3110_remove(struct i2c_client *client) data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1); ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, - data->ctl_reg1 & ~MAG3110_AC_MASK); + data->ctl_reg1 & ~MAG3110_AC_MASK); free_irq(client->irq, data); input_unregister_polled_device(data->poll_dev); @@ -509,7 +518,7 @@ static int mag3110_suspend(struct i2c_client *client, pm_message_t mesg) if (data->active == MAG_ACTIVED) { data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1); ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, - data->ctl_reg1 & ~MAG3110_AC_MASK); + data->ctl_reg1 & ~MAG3110_AC_MASK); } return ret; } @@ -521,12 +530,12 @@ static int mag3110_resume(struct i2c_client *client) struct mag3110_data *data = i2c_get_clientdata(client); if (data->active == MAG_ACTIVED) { ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, - data->ctl_reg1); + data->ctl_reg1); if (data->ctl_reg1 & MAG3110_AC_MASK) { - /* Read out MSB data to clear interrupt flag automatically */ + /* Read out MSB data to clear interrupt automatically*/ mag3110_read_block_data(client, MAG3110_OUT_X_MSB, - MAG3110_XYZ_DATA_LEN, tmp_data); + MAG3110_XYZ_DATA_LEN, tmp_data); } } return ret; @@ -545,7 +554,7 @@ static const struct i2c_device_id mag3110_id[] = { MODULE_DEVICE_TABLE(i2c, mag3110_id); static struct i2c_driver mag3110_driver = { .driver = {.name = MAG3110_DRV_NAME, - .owner = THIS_MODULE,}, + .owner = THIS_MODULE,}, .suspend = mag3110_suspend, .resume = mag3110_resume, .probe = mag3110_probe, diff --git a/drivers/hwmon/mxc_mma8451.c b/drivers/hwmon/mxc_mma8451.c index 110ff3485e3f..d144cbcbacdb 100644 --- a/drivers/hwmon/mxc_mma8451.c +++ b/drivers/hwmon/mxc_mma8451.c @@ -2,7 +2,7 @@ * mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion * Detection Sensor * - * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. 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 @@ -33,20 +33,30 @@ #include <linux/hwmon.h> #include <linux/input-polldev.h> +#define MMA8451_DRV_NAME "mma8451" #define MMA8451_I2C_ADDR 0x1C #define MMA8451_ID 0x1A #define MMA8452_ID 0x2A #define MMA8453_ID 0x3A -#define POLL_INTERVAL_MIN 1 -#define POLL_INTERVAL_MAX 500 -#define POLL_INTERVAL 100 /* msecs */ -#define INPUT_FUZZ 32 -#define INPUT_FLAT 32 +#define POLL_INTERVAL_MIN 20 +#define POLL_INTERVAL_MAX 1000 +#define POLL_INTERVAL 500 +#define INPUT_FUZZ 128 +#define INPUT_FLAT 128 #define MODE_CHANGE_DELAY_MS 100 #define MMA8451_STATUS_ZYXDR 0x08 -#define MMA8451_BUF_SIZE 7 +#define MMA8451_BUF_SIZE 6 + +#define DR_1_25MS 0 +#define DR_2_5MS 1 +#define DR_5_0MS 2 +#define DR_10_0MS 3 +#define DR_20_0MS 4 +#define DR_80_0MS 5 +#define DR_160_0MS 6 +#define DR_640_0MS 7 /* register enum for mma8451 registers */ enum { @@ -106,8 +116,8 @@ enum { }; /* The sensitivity is represented in counts/g. In 2g mode the -sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512 -counts/g and in 8g mode the sensitivity is 256 counts/g. + sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512 + counts/g and in 8g mode the sensitivity is 256 counts/g. */ enum { MODE_2G = 0, @@ -135,15 +145,15 @@ static struct i2c_client *mma8451_i2c_client; static int senstive_mode = MODE_2G; static int ACCHAL[8][3][3] = { - { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} }, - { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} }, - { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} }, - { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }, - - { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} }, - { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} }, - { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} }, - { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} }, + {{ 0, -1, 0}, { 1, 0, 0}, {0, 0, 1} }, + {{-1, 0, 0}, { 0, -1, 0}, {0, 0, 1} }, + {{ 0, 1, 0}, {-1, 0, 0}, {0, 0, 1} }, + {{ 1, 0, 0}, { 0, 1, 0}, {0, 0, 1} }, + + {{ 0, -1, 0}, {-1, 0, 0}, {0, 0, -1} }, + {{-1, 0, 0}, { 0, 1, 0}, {0, 0, -1} }, + {{ 0, 1, 0}, { 1, 0, 0}, {0, 0, -1} }, + {{ 1, 0, 0}, { 0, -1, 0}, {0, 0, -1} }, }; static DEFINE_MUTEX(mma8451_lock); @@ -154,10 +164,12 @@ static int mma8451_adjust_position(short *x, short *y, short *z) int position = mma_status.position; if (position < 0 || position > 7) position = 0; + rawdata[0] = *x; rawdata[1] = *y; rawdata[2] = *z; - for (i = 0; i < 3; i++) { + + for (i = 0; i < 3 ; i++) { data[i] = 0; for (j = 0; j < 3; j++) data[i] += rawdata[j] * ACCHAL[position][i][j]; @@ -172,17 +184,23 @@ static int mma8451_change_mode(struct i2c_client *client, int mode) { int result; - mma_status.ctl_reg1 = 0; - result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 0); + /* Put sensor into Standby Mode by clearing the Active bit */ + mma_status.ctl_reg1 = 0x00; + result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, + mma_status.ctl_reg1); if (result < 0) goto out; + /* Write the 2g dynamic range value */ mma_status.mode = mode; result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG, - mma_status.mode); + mma_status.mode); if (result < 0) goto out; + + /* Set the Active bit and Data rate in CTRL Reg 1 */ mma_status.active = MMA_STANDBY; + mdelay(MODE_CHANGE_DELAY_MS); return 0; @@ -196,13 +214,15 @@ static int mma8451_read_data(short *x, short *y, short *z) u8 tmp_data[MMA8451_BUF_SIZE]; int ret; + /* Read 14-bit XYZ results using 6 byte */ ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client, - MMA8451_OUT_X_MSB, 7, tmp_data); + MMA8451_OUT_X_MSB, MMA8451_BUF_SIZE, tmp_data); if (ret < MMA8451_BUF_SIZE) { dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n"); return -EIO; } + /* Concatenate the MSB and LSB */ *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1]; *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3]; *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5]; @@ -213,23 +233,24 @@ static void report_abs(void) { short x, y, z; int result; - int retry = 3; mutex_lock(&mma8451_lock); if (mma_status.active == MMA_STANDBY) goto out; - /* wait for the data ready */ - do { - result = i2c_smbus_read_byte_data(mma8451_i2c_client, - MMA8451_STATUS); - retry--; - msleep(1); - } while (!(result & MMA8451_STATUS_ZYXDR) && retry > 0); - if (retry == 0) + /* Read Status register */ + result = i2c_smbus_read_byte_data(mma8451_i2c_client, MMA8451_STATUS); + + /* Check ZYXDR status bit for data available */ + if (!(result & MMA8451_STATUS_ZYXDR)) { + /* Data not ready */ goto out; + } + + /* Read XYZ data */ if (mma8451_read_data(&x, &y, &z) != 0) goto out; mma8451_adjust_position(&x, &y, &z); + /* Report XYZ data */ input_report_abs(mma8451_idev->input, ABS_X, x); input_report_abs(mma8451_idev->input, ABS_Y, y); input_report_abs(mma8451_idev->input, ABS_Z, z); @@ -244,7 +265,7 @@ static void mma8451_dev_poll(struct input_polled_dev *dev) } static ssize_t mma8451_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct i2c_client *client; u8 val; @@ -262,8 +283,8 @@ static ssize_t mma8451_enable_show(struct device *dev, } static ssize_t mma8451_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client; int ret; @@ -273,42 +294,45 @@ static ssize_t mma8451_enable_store(struct device *dev, mutex_lock(&mma8451_lock); client = mma8451_i2c_client; enable = (enable > 0) ? 1 : 0; - if (enable && mma_status.active == MMA_STANDBY) { + + if (enable && mma_status.active == MMA_STANDBY) { val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1); - ret = - i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, - val | 0x01); + /* Set the Active bit and Data rate in CTRL Reg 1 */ + val |= (DR_20_0MS<<3); + val |= 1; + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, + val); if (!ret) { mma_status.active = MMA_ACTIVED; + printk(KERN_DEBUG "mma enable setting active\n"); } - } else if (enable == 0 && mma_status.active == MMA_ACTIVED) { + } else if (enable == 0 && mma_status.active == MMA_ACTIVED) { val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1); - ret = - i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, - val & 0xFE); + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, + val & 0xFE); if (!ret) { mma_status.active = MMA_STANDBY; + printk(KERN_DEBUG "mma enable setting inactive\n"); } } mutex_unlock(&mma8451_lock); return count; } - static ssize_t mma8451_position_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { int position = 0; mutex_lock(&mma8451_lock); - position = mma_status.position; + position = mma_status.position ; mutex_unlock(&mma8451_lock); return sprintf(buf, "%d\n", position); } static ssize_t mma8451_position_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { - int position; + int position; position = simple_strtoul(buf, NULL, 10); mutex_lock(&mma8451_lock); mma_status.position = position; @@ -317,9 +341,9 @@ static ssize_t mma8451_position_store(struct device *dev, } static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, - mma8451_enable_show, mma8451_enable_store); + mma8451_enable_show, mma8451_enable_store); static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, - mma8451_position_show, mma8451_position_store); + mma8451_position_show, mma8451_position_store); static struct attribute *mma8451_attributes[] = { &dev_attr_enable.attr, @@ -332,7 +356,7 @@ static const struct attribute_group mma8451_attr_group = { }; static int __devinit mma8451_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { int result, client_id; struct input_dev *idev; @@ -341,18 +365,18 @@ static int __devinit mma8451_probe(struct i2c_client *client, mma8451_i2c_client = client; adapter = to_i2c_adapter(client->dev.parent); result = i2c_check_functionality(adapter, - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA); + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA); if (!result) goto err_out; client_id = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I); - if (client_id != MMA8451_ID && client_id != MMA8452_ID - && client_id != MMA8453_ID) { + if (client_id != MMA8451_ID && client_id != MMA8452_ID && + client_id != MMA8453_ID) { dev_err(&client->dev, - "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n", - result, MMA8451_ID, MMA8452_ID); + "read chip ID 0x%x is not equal to 0x%x \ + or 0x%x!\n", result, MMA8451_ID, MMA8452_ID); result = -EINVAL; goto err_out; } @@ -361,14 +385,15 @@ static int __devinit mma8451_probe(struct i2c_client *client, result = mma8451_change_mode(client, senstive_mode); if (result) { dev_err(&client->dev, - "error when init mma8451 chip:(%d)\n", result); + "error when init mma8451 chip:(%d)\n", result); goto err_out; } hwmon_dev = hwmon_device_register(&client->dev); if (!hwmon_dev) { result = -ENOMEM; - dev_err(&client->dev, "error when register hwmon device\n"); + dev_err(&client->dev, + "error when register hwmon device\n"); goto err_out; } @@ -417,9 +442,9 @@ static int mma8451_stop_chip(struct i2c_client *client) int ret = 0; if (mma_status.active == MMA_ACTIVED) { mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client, - MMA8451_CTRL_REG1); + MMA8451_CTRL_REG1); ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, - mma_status.ctl_reg1 & 0xFE); + mma_status.ctl_reg1 & 0xFE); } return ret; } @@ -447,25 +472,24 @@ static int mma8451_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); if (mma_status.active == MMA_ACTIVED) ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, - mma_status.ctl_reg1); + mma_status.ctl_reg1); return ret; } #endif static const struct i2c_device_id mma8451_id[] = { - {"mma8451", 0}, + {MMA8451_DRV_NAME, 0}, }; - MODULE_DEVICE_TABLE(i2c, mma8451_id); static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume); static struct i2c_driver mma8451_driver = { .driver = { - .name = "mma8451", - .owner = THIS_MODULE, - .pm = &mma8451_pm_ops, - }, + .name = MMA8451_DRV_NAME, + .owner = THIS_MODULE, + .pm = &mma8451_pm_ops, + }, .probe = mma8451_probe, .remove = __devexit_p(mma8451_remove), .id_table = mma8451_id, diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b9474aa7f043..2dcdb20e4c61 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -335,18 +335,6 @@ config KEYBOARD_MCS To compile this driver as a module, choose M here: the module will be called mcs_touchkey. -config KEYBOARD_MPR121 - tristate "Freescale MPR121 Touchkey" - depends on I2C - help - Say Y here if you have Freescale MPR121 touchkey controller - chip in your system. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called mpr121_touchkey. - config KEYBOARD_IMX tristate "IMX keypad support" depends on ARCH_MXC diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 6791e8b45289..1b0d7ad2814a 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o -obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o diff --git a/drivers/input/keyboard/mpr121.c b/drivers/input/keyboard/mpr121.c index 7aae302758c5..b5eb8e39028a 100644 --- a/drivers/input/keyboard/mpr121.c +++ b/drivers/input/keyboard/mpr121.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -30,7 +30,6 @@ #include <linux/delay.h> #include <linux/bitops.h> - struct mpr121_touchkey_data { struct i2c_client *client; struct input_dev *input_dev; @@ -88,8 +87,7 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) data->statusbits = reg; data->key_val = data->keycodes[key_num]; - input_event(input, EV_MSC, MSC_SCAN, data->key_val); - input_report_key(input, data->key_val, pressed); + input_event(input, EV_KEY, data->key_val, !!pressed); input_sync(input); dev_dbg(&client->dev, "key %d %d %s\n", key_num, data->key_val, @@ -125,6 +123,7 @@ static int mpr121_phys_init(struct mpr121_platform_data *pdata, if (ret < 0) goto err_i2c_write; } + /* setup auto-register by vdd,the formula please ref:AN3889 */ vdd = pdata->vdd_uv / 1000; usl = ((vdd - 700) * 256) / vdd; @@ -140,7 +139,7 @@ static int mpr121_phys_init(struct mpr121_platform_data *pdata, if (ret < 0) goto err_i2c_write; ret = i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, - data->keycount); + ECR_CL_BT_5BIT_VAL | (data->keycount & 0xf)); if (ret < 0) goto err_i2c_write; @@ -203,11 +202,10 @@ static int __devinit mpr_touchkey_probe(struct i2c_client *client, input_dev->keycodemax = data->keycount; for (i = 0; i < input_dev->keycodemax; i++) { - __set_bit(pdata->matrix[i], input_dev->keybit); + input_set_capability(input_dev, EV_KEY, pdata->matrix[i]); data->keycodes[i] = pdata->matrix[i]; } - input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, data); error = request_threaded_irq(client->irq, NULL, @@ -264,7 +262,8 @@ static int mpr_resume(struct i2c_client *client) if (device_may_wakeup(&client->dev)) disable_irq_wake(client->irq); - i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, data->keycount); + i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, + ECR_CL_BT_5BIT_VAL | (data->keycount & 0xf)); return 0; } diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c index 2271b59261fa..d1a1461ea97a 100644 --- a/drivers/input/misc/da9052_onkey.c +++ b/drivers/input/misc/da9052_onkey.c @@ -1,3 +1,15 @@ +/* + * Copyright(c) 2009 Dialog Semiconductor Ltd. + * Copyright (C) 2012 Freescale Semiconductor, 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. + * + * da9052_onkey.c: Onkey driver for DA9052 + */ + #include <linux/module.h> #include <linux/init.h> #include <linux/input.h> @@ -14,6 +26,9 @@ struct da9052_onkey_data { struct input_dev *input; }; +/* Flag to enable key events during suspend */ +static bool enable_onkey_events; + static void da9052_onkey_report_event(struct da9052_eh_nb *eh_data, unsigned int event) { @@ -33,9 +48,12 @@ static void da9052_onkey_report_event(struct da9052_eh_nb *eh_data, da9052_unlock(da9052_onkey->da9052); msg.data = msg.data & DA9052_EVENTB_ENONKEY; - input_report_key(da9052_onkey->input, KEY_POWER, msg.data); - input_sync(da9052_onkey->input); - printk(KERN_INFO "DA9052 ONKEY EVENT REPORTED \n"); + /* We need onkey events only in suspend mode */ + if (enable_onkey_events) { + input_report_key(da9052_onkey->input, KEY_POWER, msg.data); + input_sync(da9052_onkey->input); + } + pr_debug("DA9052 ONKEY EVENT REPORTED\n"); } static int __devinit da9052_onkey_probe(struct platform_device *pdev) @@ -105,12 +123,34 @@ static int __devexit da9052_onkey_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int da9052_onkey_suspend(struct device *dev) +{ + enable_onkey_events = true; + return 0; +} + +static int da9052_onkey_resume(struct device *dev) +{ + enable_onkey_events = false; + return 0; +} + +static const struct dev_pm_ops da9052_onkey_pm_ops = { + .suspend = da9052_onkey_suspend, + .resume = da9052_onkey_resume, +}; +#else +static const struct dev_pm_ops da9052_onkey_pm_ops = {}; +#endif + static struct platform_driver da9052_onkey_driver = { .probe = da9052_onkey_probe, .remove = __devexit_p(da9052_onkey_remove), .driver = { .name = "da9052-onkey", .owner = THIS_MODULE, + .pm = &da9052_onkey_pm_ops, } }; diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 321146efbff3..9a149e4e43da 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -1,7 +1,7 @@ /* * Driver for EETI eGalax Multiple Touch Controller * - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. * * based on max11801_ts.c * @@ -54,7 +54,7 @@ /* Multiple Touch Mode */ #define REPORT_MODE_MTTOUCH 0x4 -#define MAX_SUPPORT_POINTS 5 +#define MAX_SUPPORT_POINTS 2 #define EVENT_VALID_OFFSET 7 #define EVENT_VALID_MASK (0x1 << EVENT_VALID_OFFSET) @@ -67,20 +67,56 @@ #define EGALAX_MAX_X 32760 #define EGALAX_MAX_Y 32760 +#define EGALAX_MAX_Z 2048 #define EGALAX_MAX_TRIES 100 +struct finger_info { + s16 x; + s16 y; + s16 z; +}; + struct egalax_ts { struct i2c_client *client; struct input_dev *input_dev; #ifdef CONFIG_EARLYSUSPEND struct early_suspend es_handler; #endif + u32 finger_mask; + struct finger_info fingers[MAX_SUPPORT_POINTS]; }; +static void report_input_data(struct egalax_ts *data) +{ + int i; + int num_fingers_down; + + num_fingers_down = 0; + for (i = 0; i < MAX_SUPPORT_POINTS; i++) { + if (data->fingers[i].z == -1) + continue; + + input_report_abs(data->input_dev, ABS_MT_POSITION_X, + data->fingers[i].x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, + data->fingers[i].y); + input_report_abs(data->input_dev, ABS_MT_PRESSURE, + data->fingers[i].z); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1); + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, i); + input_mt_sync(data->input_dev); + num_fingers_down++; + } + data->finger_mask = 0; + + if (num_fingers_down == 0) + input_mt_sync(data->input_dev); + input_sync(data->input_dev); +} + static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) { struct egalax_ts *data = dev_id; - struct input_dev *input_dev = data->input_dev; struct i2c_client *client = data->client; u8 buf[MAX_I2C_DATA_LEN]; int id, ret, x, y, z; @@ -89,6 +125,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) u8 state; do { + memset(buf, 0, MAX_I2C_DATA_LEN); do { ret = i2c_master_recv(client, buf, MAX_I2C_DATA_LEN); } while (ret == -EAGAIN && tries++ < EGALAX_MAX_TRIES); @@ -110,27 +147,32 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) id = (state & EVENT_ID_MASK) >> EVENT_ID_OFFSET; down = state & EVENT_DOWN_UP; - if (!valid || id > MAX_SUPPORT_POINTS) { + if (!valid || id >= MAX_SUPPORT_POINTS) { dev_dbg(&client->dev, "point invalid\n"); return IRQ_HANDLED; } - input_mt_slot(input_dev, id); - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, down); + if (data->finger_mask & (1U << id)) + report_input_data(data); + + if (!down) { + data->fingers[id].z = -1; + data->finger_mask |= 1U << id; + } else { + data->fingers[id].x = x; + data->fingers[id].y = y; + data->fingers[id].z = z; + data->finger_mask |= 1U << id; + } - dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d", + dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d\n", (down ? "down" : "up"), id, x, y, z); - if (down) { - input_report_abs(input_dev, ABS_MT_POSITION_X, x); - input_report_abs(input_dev, ABS_MT_POSITION_Y, y); - input_report_abs(input_dev, ABS_MT_PRESSURE, z); - } - - input_mt_report_pointer_emulation(input_dev, true); - input_sync(input_dev); } while (gpio_get_value(irq_to_gpio(client->irq)) == 0); + if (data->finger_mask) + report_input_data(data); + return IRQ_HANDLED; } @@ -138,7 +180,8 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) static int egalax_wake_up_device(struct i2c_client *client) { int gpio = irq_to_gpio(client->irq); - int ret; + u8 buf[MAX_I2C_DATA_LEN]; + int ret, tries = 0; ret = gpio_request(gpio, "egalax_irq"); if (ret < 0) { @@ -148,11 +191,17 @@ static int egalax_wake_up_device(struct i2c_client *client) } /* wake up controller via an falling edge on IRQ gpio. */ gpio_direction_output(gpio, 1); - gpio_direction_output(gpio, 0); + gpio_set_value(gpio, 0); gpio_set_value(gpio, 1); /* controller should be waken up, return irq. */ gpio_direction_input(gpio); gpio_free(gpio); + + /* If the touch controller has some data pending, read it */ + /* or the INT line will remian low */ + while ((gpio_get_value(gpio) == 0) && (tries++ < EGALAX_MAX_TRIES)) + i2c_master_recv(client, buf, MAX_I2C_DATA_LEN); + return 0; } @@ -210,22 +259,22 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, input_dev->dev.parent = &client->dev; __set_bit(EV_ABS, input_dev->evbit); - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(BTN_TOUCH, input_dev->keybit); - input_set_abs_params(input_dev, ABS_X, 0, EGALAX_MAX_X, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, EGALAX_MAX_Y, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0); - input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS); + input_set_abs_params(input_dev, + ABS_MT_PRESSURE, 0, EGALAX_MAX_Z, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, + MAX_SUPPORT_POINTS-1, 0, 0); input_set_drvdata(input_dev, data); ret = request_threaded_irq(client->irq, NULL, egalax_ts_interrupt, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "egalax_ts", data); + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "egalax_ts", data); if (ret < 0) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_dev; diff --git a/drivers/input/touchscreen/p1003_ts.c b/drivers/input/touchscreen/p1003_ts.c index 39e9c6573727..d725e12006d8 100644 --- a/drivers/input/touchscreen/p1003_ts.c +++ b/drivers/input/touchscreen/p1003_ts.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Freescale Semiconductor, Inc. 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 @@ -24,6 +24,7 @@ #include <linux/i2c.h> #include <linux/input.h> #include <linux/irq.h> +#include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/fsl_devices.h> @@ -42,7 +43,6 @@ struct p1003_priv { unsigned int irq; struct work_struct work; struct point_state old_state; - struct workqueue_struct *workqueue; }; #define POINTER_DATA_LEN 9 @@ -115,18 +115,17 @@ static int p1003_i2c_read_packet(struct i2c_client *client, char *value) POINTER_DATA_LEN, (u8 *) value); } -static void p1003_work(struct work_struct *work) +static irqreturn_t p1003_irq(int irq, void *handle) { - struct p1003_priv *p1003 = container_of(work, struct p1003_priv, work); + struct p1003_priv *p1003 = handle; struct i2c_client *client = p1003->client; - struct p1003_ts_platform_data *pdata = client->dev.platform_data; struct input_dev *input = p1003->input; struct point_state *old_state = &p1003->old_state; char data[POINTER_DATA_LEN]; int x1, x2, y1, y2; /* the sample can only be read when intr pin low */ - while (!pdata->hw_status()) { + do { if (p1003_i2c_read_packet(client, data) < 0) { dev_err(&client->dev, "read i2c packet failed\n"); continue; @@ -184,7 +183,7 @@ static void p1003_work(struct work_struct *work) old_state->x2 = x2; old_state->y2 = y2; } - }; + } while (gpio_get_value(irq_to_gpio(p1003->irq)) == 0); /* the irq is high now, means figure is leave the panel, send * release to user space. */ @@ -194,12 +193,7 @@ static void p1003_work(struct work_struct *work) input_report_abs(input, ABS_PRESSURE, 0); input_sync(input); old_state->state = data[0]; -} -static irqreturn_t p1003_irq(int irq, void *handle) -{ - struct p1003_priv *p1003 = handle; - queue_work(p1003->workqueue, &p1003->work); return IRQ_HANDLED; } @@ -231,7 +225,6 @@ static int __devinit p1003_probe(struct i2c_client *client, int ret, xmax, ymax; struct p1003_priv *p1003; struct input_dev *input_dev; - struct p1003_ts_platform_data *pdata = client->dev.platform_data; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { @@ -239,11 +232,6 @@ static int __devinit p1003_probe(struct i2c_client *client, return -EIO; } - if (!pdata || !pdata->hw_status) { - dev_err(&client->dev, "No hw status function!\n"); - return -EIO; - } - p1003 = kzalloc(sizeof(struct p1003_priv), GFP_KERNEL); if (!p1003) return -ENOMEM; @@ -257,14 +245,6 @@ static int __devinit p1003_probe(struct i2c_client *client, p1003->client = client; p1003->irq = client->irq; p1003->input = input_dev; - p1003->workqueue = create_singlethread_workqueue("p1003"); - INIT_WORK(&p1003->work, p1003_work); - - if (p1003->workqueue == NULL) { - dev_err(&client->dev, "couldn't create workqueue\n"); - ret = -ENOMEM; - goto err_free_dev; - } snprintf(p1003->phys, sizeof(p1003->phys), "%s/input0", dev_name(&client->dev)); @@ -272,7 +252,7 @@ static int __devinit p1003_probe(struct i2c_client *client, if (read_max_range(client, &xmax, &ymax) < 0) { dev_err(&client->dev, "couldn't read panel infomation.\n"); ret = -EIO; - goto err_free_wq; + goto err_free_dev; } input_dev->name = "HannStar P1003 Touchscreen"; @@ -292,32 +272,27 @@ static int __devinit p1003_probe(struct i2c_client *client, ret = input_register_device(input_dev); if (ret) - goto err_free_wq; + goto err_free_dev; i2c_set_clientdata(client, p1003); ret = sysfs_create_group(&client->dev.kobj, &p1003_attr_group); if (ret) - goto err_free_wq; + goto err_free_dev; /* set irq type to edge falling */ - set_irq_type(p1003->irq, IRQF_TRIGGER_FALLING); - ret = request_irq(p1003->irq, p1003_irq, 0, - client->dev.driver->name, p1003); + ret = request_threaded_irq(client->irq, NULL, p1003_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->dev.driver->name, p1003); if (ret < 0) { dev_err(&client->dev, "failed to register irq %d!\n", p1003->irq); goto err_unreg_dev; } - if (!pdata->hw_status()) - queue_work(p1003->workqueue, &p1003->work); - return 0; err_unreg_dev: input_unregister_device(input_dev); -err_free_wq: - destroy_workqueue(p1003->workqueue); err_free_dev: input_free_device(input_dev); err_free_mem: @@ -329,8 +304,6 @@ static int __devexit p1003_remove(struct i2c_client *client) { struct p1003_priv *p1003 = i2c_get_clientdata(client); free_irq(p1003->irq, p1003); - cancel_work_sync(&p1003->work); - destroy_workqueue(p1003->workqueue); input_unregister_device(p1003->input); input_free_device(p1003->input); kfree(p1003); diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 8b4a658ceb50..928b1074748b 100755 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -2,6 +2,7 @@ * da9052-core.c -- Device access for Dialog DA9052 * * Copyright(c) 2009 Dialog Semiconductor Ltd. + * Copyright (C) 2012 Freescale Semiconductor, Inc. * * Author: Dialog Semiconductor Ltd <dchen@diasemi.com> * @@ -34,6 +35,7 @@ struct da9052_eh_nb eve_nb_array[EVE_CNT]; static struct da9052_ssc_ops ssc_ops; struct mutex manconv_lock; static struct semaphore eve_nb_array_lock; +static struct da9052 *da9052_data; void da9052_lock(struct da9052 *da9052) { @@ -248,17 +250,16 @@ static int process_events(struct da9052 *da9052, int events_sts) /* Check if interrupt is received for this event */ if (!((tmp_events_sts >> cnt) & 0x1)) /* Event bit is not set for this event */ - /* Move to next event */ + /* Move to next priority event */ continue; if (event == PEN_DOWN_EVE) { if (list_empty(&(eve_nb_array[event].nb_list))) continue; } - /* Event bit is set, execute all registered call backs */ if (down_interruptible(&eve_nb_array_lock)){ - printk(KERN_CRIT "Can't acquire eve_nb_array_lock \n"); + printk(KERN_CRIT "Can't acquire eve_nb_array_lock\n"); return -EIO; } @@ -281,14 +282,11 @@ void eh_workqueue_isr(struct work_struct *work) container_of(work, struct da9052, eh_isr_work); struct da9052_ssc_msg eve_data[4]; - struct da9052_ssc_msg eve_mask_data[4]; int events_sts, ret; - u32 mask; unsigned char cnt = 0; /* nIRQ is asserted, read event registeres to know what happened */ events_sts = 0; - mask = 0; /* Prepare ssc message to read all four event registers */ for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) { @@ -296,13 +294,7 @@ void eh_workqueue_isr(struct work_struct *work) eve_data[cnt].data = 0; } - /* Prepare ssc message to read all four event registers */ - for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) { - eve_mask_data[cnt].addr = (DA9052_IRQMASKA_REG + cnt); - eve_mask_data[cnt].data = 0; - } - - /* Now read all event and mask registers */ + /* Now read all event registers */ da9052_lock(da9052); ret = da9052_ssc_read_many(da9052,eve_data, DA9052_EVE_REGISTERS); @@ -312,22 +304,10 @@ void eh_workqueue_isr(struct work_struct *work) return; } - ret = da9052_ssc_read_many(da9052,eve_mask_data, DA9052_EVE_REGISTERS); - if (ret) { - enable_irq(da9052->irq); - da9052_unlock(da9052); - return; - } /* Collect all events */ for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) - events_sts |= (eve_data[cnt].data << (DA9052_EVE_REGISTER_SIZE - * cnt)); - /* Collect all mask */ - for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) - mask |= (eve_mask_data[cnt].data << (DA9052_EVE_REGISTER_SIZE - * cnt)); - events_sts &= ~mask; - da9052_unlock(da9052); + events_sts |= ((eve_data[cnt].data&0xff) << + (DA9052_EVE_REGISTER_SIZE * cnt)); /* Check if we really got any event */ if (events_sts == 0) { @@ -335,6 +315,7 @@ void eh_workqueue_isr(struct work_struct *work) da9052_unlock(da9052); return; } + da9052_unlock(da9052); /* Process all events occurred */ process_events(da9052, events_sts); @@ -376,7 +357,7 @@ static int da9052_add_subdevice_pdata(struct da9052 *da9052, struct mfd_cell cell = { .name = name, .platform_data = pdata, - .data_size = pdata_size, + .pdata_size = pdata_size, }; return mfd_add_devices(da9052->dev, -1, &cell, 1, NULL, 0); } @@ -399,6 +380,7 @@ static int add_da9052_devices(struct da9052 *da9052) }; struct da9052_tsi_platform_data tsi_data = *(pdata->tsi_data); + struct da9052_bat_platform_data bat_data = *(pdata->bat_data); if (pdata && pdata->init) { ret = pdata->init(da9052); @@ -406,7 +388,6 @@ static int add_da9052_devices(struct da9052 *da9052) return ret; } else pr_err("No platform initialisation supplied\n"); - ret = da9052_add_subdevice(da9052, "da9052-rtc"); if (ret) return ret; @@ -449,7 +430,8 @@ static int add_da9052_devices(struct da9052 *da9052) if (ret) return ret; - ret = da9052_add_subdevice(da9052, "da9052-bat"); + ret = da9052_add_subdevice_pdata(da9052, "da9052-bat", + &bat_data, sizeof(bat_data)); if (ret) return ret; @@ -493,6 +475,7 @@ int da9052_ssc_init(struct da9052 *da9052) ssc_ops.read_many = da9052_i2c_read_many; } else return -1; + /* Assign the EH notifier block register/de-register functions */ da9052->register_event_notifier = eh_register_nb; da9052->unregister_event_notifier = eh_unregister_nb; @@ -504,16 +487,34 @@ int da9052_ssc_init(struct da9052 *da9052) add_da9052_devices(da9052); INIT_WORK(&da9052->eh_isr_work, eh_workqueue_isr); + ssc_msg.addr = DA9052_IRQMASKA_REG; ssc_msg.data = 0xff; da9052->write(da9052, &ssc_msg); ssc_msg.addr = DA9052_IRQMASKC_REG; ssc_msg.data = 0xff; da9052->write(da9052, &ssc_msg); + + /* read chip version */ + ssc_msg.addr = DA9052_CHIPID_REG; + da9052->read(da9052, &ssc_msg); + pr_info("DA9053 chip ID reg read=0x%x ", ssc_msg.data); + if ((ssc_msg.data & DA9052_CHIPID_MRC) == 0x80) { + da9052->chip_version = DA9053_VERSION_AA; + pr_info("AA version probed\n"); + } else if ((ssc_msg.data & DA9052_CHIPID_MRC) == 0xa0) { + da9052->chip_version = DA9053_VERSION_BB; + pr_info("BB version probed\n"); + } else { + da9052->chip_version = 0; + pr_info("unknown chip version\n"); + } + if (request_irq(da9052->irq, da9052_eh_isr, IRQ_TYPE_LEVEL_LOW, DA9052_EH_DEVICE_NAME, da9052)) return -EIO; enable_irq_wake(da9052->irq); + da9052_data = da9052; return 0; } @@ -530,6 +531,27 @@ void da9052_ssc_exit(struct da9052 *da9052) return; } +void da9053_power_off(void) +{ + struct da9052_ssc_msg ssc_msg; + struct da9052_ssc_msg ssc_msg_dummy[2]; + if (!da9052_data) + return; + + ssc_msg.addr = DA9052_CONTROLB_REG; + da9052_data->read(da9052_data, &ssc_msg); + ssc_msg_dummy[0].addr = DA9052_CONTROLB_REG; + ssc_msg_dummy[0].data = ssc_msg.data | DA9052_CONTROLB_SHUTDOWN; + ssc_msg_dummy[1].addr = DA9052_GPID9_REG; + ssc_msg_dummy[1].data = 0; + da9052_data->write_many(da9052_data, &ssc_msg_dummy[0], 2); +} + +int da9053_get_chip_version(void) +{ + return da9052_data->chip_version; +} + MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>"); MODULE_DESCRIPTION("DA9052 MFD Core"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 4f050896d962..005b3f46da41 100755 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2009 Dialog Semiconductor Ltd. + * Copyright (C) 2012 Freescale Semiconductor, 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 @@ -21,23 +22,21 @@ static struct da9052 *da9052_i2c; static int da9052_i2c_is_connected(void) { + struct da9052_ssc_msg msg; + int retries = 10, ret = -1; + + msg.addr = DA9052_INTERFACE_REG; + do { + /* Test i2c connectivity by reading the GPIO_0-1 register */ + if (0 != da9052_i2c_read(da9052_i2c, &msg)) { + printk(KERN_INFO"da9052_i2c_is_connected - i2c read failed.....\n"); + } else { + printk(KERN_INFO"da9052_i2c_is_connected - i2c read success....\n"); + ret = 0; + } + } while (ret != 0 && retries--); - struct da9052_ssc_msg msg; - - //printk("Entered da9052_i2c_is_connected.............\n"); - - msg.addr = DA9052_INTERFACE_REG; - - /* Test spi connectivity by performing read of the GPIO_0-1 register */ - if ( 0 != da9052_i2c_read(da9052_i2c, &msg)) { - printk("da9052_i2c_is_connected - i2c read failed.............\n"); - return -1; - } - else { - printk("da9052_i2c_is_connected - i2c read success..............\n"); - return 0; - } - + return ret; } static int __devinit da9052_i2c_probe(struct i2c_client *client, diff --git a/drivers/mfd/mc-pmic-core.c b/drivers/mfd/mc-pmic-core.c index db46ef1da050..3d3a09d62cbb 100644 --- a/drivers/mfd/mc-pmic-core.c +++ b/drivers/mfd/mc-pmic-core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. 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 @@ -505,7 +505,6 @@ mc_pmic_add_subdevice_pdata(struct mc_pmic *mc_pmic, struct mfd_cell cell = { .platform_data = pdata, - .data_size = pdata_size, }; /* there is no asnprintf in the kernel :-( */ @@ -556,7 +555,6 @@ mc_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) if (ret) { err_mask: - err_revision: mc_pmic_unlock(mc_pmic); dev_set_drvdata(&client->dev, NULL); kfree(mc_pmic); diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 3dea9b5b29ff..074b5952a629 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -34,6 +34,7 @@ #define SDHCI_VENDOR_SPEC 0xC0 #define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002 +#define SDHCI_MIX_CTRL_AC12EN (1 << 2) #define SDHCI_MIX_CTRL_AC23EN (1 << 7) #define SDHCI_MIX_CTRL_EXE_TUNE (1 << 22) #define SDHCI_MIX_CTRL_SMPCLK_SEL (1 << 23) @@ -291,9 +292,12 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; u32 data; + struct esdhc_platform_data *boarddata + = host->mmc->parent->platform_data; if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))) { - if (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP) + if ((boarddata->always_present) || + (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)) /* * these interrupts won't work with a custom * card_detect gpio (only applied to mx25/35) @@ -556,9 +560,12 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } imx_data->scratchpad = val; - if (val & SDHCI_TRNS_AUTO_CMD23) + if (cpu_is_mx6() && (val & SDHCI_TRNS_AUTO_CMD23)) imx_data->scratchpad |= SDHCI_MIX_CTRL_AC23EN; + if (cpu_is_mx5() && (val & SDHCI_TRNS_AUTO_CMD12)) + imx_data->scratchpad |= SDHCI_MIX_CTRL_AC12EN; + return; case SDHCI_COMMAND: if ((host->cmd->opcode == MMC_STOP_TRANSMISSION || @@ -782,9 +789,6 @@ static irqreturn_t cd_irq(int irq, void *data) imx_data->scratchpad &= ~SDHCI_MIX_CTRL_SMPCLK_SEL; } - esdhc_reset(sdhost); - mdelay(1); - tasklet_schedule(&sdhost->card_tasklet); return IRQ_HANDLED; }; @@ -823,13 +827,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd /* * on mx6dl TO 1.1, ADMA can work when ahb bus frequency is low, - * like 24Mhz. + * like 24Mhz. MX53 does have working ADMA. */ - if (mx6dl_revision() >= IMX_CHIP_REVISION_1_1) + if (mx6dl_revision() >= IMX_CHIP_REVISION_1_1 || cpu_is_mx53()) host->quirks &= ~SDHCI_QUIRK_BROKEN_ADMA; if (cpu_is_mx6()) - host->quirks2 |= SDHCI_QUIRK_BROKEN_AUTO_CMD23, + host->quirks2 |= SDHCI_QUIRK_BROKEN_AUTO_CMD23; /* write_protect can't be routed to controller, use gpio */ sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d1fe3d3f73ab..a10037fa6a9b 100755 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2656,7 +2656,7 @@ int sdhci_add_host(struct sdhci_host *host) } else mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; - mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; + mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE; if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) host->flags |= SDHCI_AUTO_CMD12; @@ -2667,6 +2667,7 @@ int sdhci_add_host(struct sdhci_host *host) ((host->flags & SDHCI_USE_ADMA) || !(host->flags & SDHCI_USE_SDMA))) { host->flags |= SDHCI_AUTO_CMD23; + mmc->caps |= MMC_CAP_CMD23; DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc)); } else { DBG("%s: Auto-CMD23 unavailable\n", mmc_hostname(mmc)); diff --git a/drivers/mxc/amd-gpu/common/gsl_memmgr.c b/drivers/mxc/amd-gpu/common/gsl_memmgr.c index 75f250ae59b1..3248f6d46554 100644 --- a/drivers/mxc/amd-gpu/common/gsl_memmgr.c +++ b/drivers/mxc/amd-gpu/common/gsl_memmgr.c @@ -479,6 +479,8 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m unsigned int blksize; unsigned int baseaddr, alignedbaseaddr, alignfragment; int freeblk, alignmentshift; + memblk_t *ptrbest = NULL; + unsigned int fitsize = ~0UL; kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_TRACE, "--> int kgsl_memarena_alloc(gsl_memarena_t *memarena=0x%08x, gsl_flags_t flags=0x%08x, int size=%d, gsl_memdesc_t *memdesc=%M)\n", memarena, flags, size, memdesc ); @@ -542,17 +544,33 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m do { + int aba; // align base address - baseaddr = ptrfree->blkaddr + memarena->gpubaseaddr; - alignedbaseaddr = gsl_memarena_alignaddr(baseaddr, alignmentshift); + baseaddr = ptrfree->blkaddr + memarena->gpubaseaddr; + aba = gsl_memarena_alignaddr(baseaddr, alignmentshift); - alignfragment = alignedbaseaddr - baseaddr; - - if (ptrfree->blksize >= blksize + alignfragment) - { - result = GSL_SUCCESS; - freeblk = 1; - + if (aba - baseaddr == 0 && ptrfree->blksize == blksize) { + ptrbest = ptrfree; + alignfragment = aba - baseaddr; + alignedbaseaddr = aba; + result = GSL_SUCCESS; + break; + } + + if ((ptrfree->blksize >= blksize + aba - baseaddr) && + (fitsize > ptrfree->blksize)) { + fitsize = ptrfree->blksize; + alignfragment = aba - baseaddr; + alignedbaseaddr = aba; + result = GSL_SUCCESS; + ptrbest = ptrfree; + } + + ptrfree = ptrfree->next; + + } while (ptrfree != memarena->freelist.allocrover); + + if (ptrbest) { memdesc->gpuaddr = alignedbaseaddr; memdesc->hostptr = kgsl_memarena_gethostptr(memarena, memdesc->gpuaddr); memdesc->size = blksize; @@ -561,50 +579,41 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m { // insert new node to handle newly created (small) fragment p = kgsl_memarena_getmemblknode(memarena); - p->blkaddr = ptrfree->blkaddr; + p->blkaddr = ptrbest->blkaddr; p->blksize = alignfragment; - p->next = ptrfree; - p->prev = ptrfree->prev; - ptrfree->prev->next = p; - ptrfree->prev = p; + p->next = ptrbest; + p->prev = ptrbest->prev; + ptrbest->prev->next = p; + ptrbest->prev = p; - if (ptrfree == memarena->freelist.head) - { - memarena->freelist.head = p; - } + if (ptrbest == memarena->freelist.head) + memarena->freelist.head = p; } - ptrfree->blkaddr += alignfragment + blksize; - ptrfree->blksize -= alignfragment + blksize; + ptrbest->blkaddr += alignfragment + blksize; + ptrbest->blksize -= alignfragment + blksize; - memarena->freelist.allocrover = ptrfree; + memarena->freelist.allocrover = ptrbest; - if (ptrfree->blksize == 0 && ptrfree != ptrlast) - { - ptrfree->prev->next = ptrfree->next; - ptrfree->next->prev = ptrfree->prev; - if (ptrfree == memarena->freelist.head) - { - memarena->freelist.head = ptrfree->next; - } - if (ptrfree == memarena->freelist.allocrover) - { - memarena->freelist.allocrover = ptrfree->next; - } - if (ptrfree == memarena->freelist.freerover) - { - memarena->freelist.freerover = ptrfree->prev; - } - p = ptrfree; - ptrfree = ptrfree->prev; - kgsl_memarena_releasememblknode(memarena, p); - } - } + if (ptrbest->blksize == 0 && ptrbest != ptrlast) { + ptrbest->prev->next = ptrbest->next; + ptrbest->next->prev = ptrbest->prev; - ptrfree = ptrfree->next; + if (ptrbest == memarena->freelist.head) + memarena->freelist.head = ptrbest->next; + + if (ptrbest == memarena->freelist.allocrover) + memarena->freelist.allocrover = ptrbest->next; + + if (ptrbest == memarena->freelist.freerover) + memarena->freelist.freerover = ptrbest->prev; - } while (!freeblk && ptrfree != memarena->freelist.allocrover); + p = ptrbest; + ptrbest = ptrbest->prev; + kgsl_memarena_releasememblknode(memarena, p); + } + } GSL_MEMARENA_UNLOCK(); diff --git a/drivers/mxc/amd-gpu/common/gsl_mmu.c b/drivers/mxc/amd-gpu/common/gsl_mmu.c index 810a058a515d..8259896775b6 100644 --- a/drivers/mxc/amd-gpu/common/gsl_mmu.c +++ b/drivers/mxc/amd-gpu/common/gsl_mmu.c @@ -89,7 +89,8 @@ const unsigned int GSL_PT_PAGE_AP[4] = {(GSL_PT_PAGE_READ | GSL_PT_PAGE_WRITE), #define GSL_PT_MAP_SETBITS(pte, bits) (GSL_PT_MAP_GET(pte) |= (((unsigned int) bits) & GSL_PT_PAGE_AP_MASK)) #define GSL_PT_MAP_SETADDR(pte, pageaddr) (GSL_PT_MAP_GET(pte) = (GSL_PT_MAP_GET(pte) & ~GSL_PT_PAGE_ADDR_MASK) | (((unsigned int) pageaddr) & GSL_PT_PAGE_ADDR_MASK)) -#define GSL_PT_MAP_RESET(pte) (GSL_PT_MAP_GET(pte) = 0) +/* reserve RV and WV bits to work around READ_PROTECTION_ERROR in some cases */ +#define GSL_PT_MAP_RESET(pte) (GSL_PT_MAP_GET(pte) &= ~GSL_PT_PAGE_ADDR_MASK) #define GSL_PT_MAP_RESETBITS(pte, bits) (GSL_PT_MAP_GET(pte) &= ~(((unsigned int) bits) & GSL_PT_PAGE_AP_MASK)) #define GSL_MMU_VIRT_TO_PAGE(va) *((unsigned int *)(pagetable->base.gpuaddr + (GSL_PT_ENTRY_GET(va) * GSL_PT_ENTRY_SIZEBYTES))) @@ -708,6 +709,16 @@ kgsl_mmu_map(gsl_mmu_t *mmu, gpuaddr_t gpubaseaddr, const gsl_scatterlist_t *sca //---------------------------------------------------------------------------- +static bool is_superpte_empty(gsl_pagetable_t *pagetable, unsigned int superpte) +{ + int i; + for (i = 0; i < GSL_PT_SUPER_PTE; i++) { + if (GSL_PT_MAP_GET(superpte+i)) + return false; + } + return true; +} + int kgsl_mmu_unmap(gsl_mmu_t *mmu, gpuaddr_t gpubaseaddr, int range, unsigned int pid) { @@ -777,7 +788,10 @@ kgsl_mmu_unmap(gsl_mmu_t *mmu, gpuaddr_t gpubaseaddr, int range, unsigned int pi { do { - pagetable->last_superpte -= GSL_PT_SUPER_PTE; + if (is_superpte_empty(pagetable, superpte)) + pagetable->last_superpte -= GSL_PT_SUPER_PTE; + else + break; } while (!GSL_PT_MAP_GETADDR(pagetable->last_superpte) && pagetable->last_superpte >= GSL_PT_SUPER_PTE); } diff --git a/drivers/mxc/amd-gpu/common/gsl_ringbuffer.c b/drivers/mxc/amd-gpu/common/gsl_ringbuffer.c index fb05ff3cbe14..112fd086cf81 100644 --- a/drivers/mxc/amd-gpu/common/gsl_ringbuffer.c +++ b/drivers/mxc/amd-gpu/common/gsl_ringbuffer.c @@ -342,8 +342,6 @@ kgsl_ringbuffer_checkpm4(unsigned int* cmds, unsigned int sizedwords, int pmodeo static void kgsl_ringbuffer_submit(gsl_ringbuffer_t *rb) { - unsigned int value; - kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "--> static void kgsl_ringbuffer_submit(gsl_ringbuffer_t *rb=0x%08x)\n", rb ); diff --git a/drivers/mxc/amd-gpu/common/pm4_microcode.inl b/drivers/mxc/amd-gpu/common/pm4_microcode.inl index 03f6f4cd35e4..058548b41522 100644 --- a/drivers/mxc/amd-gpu/common/pm4_microcode.inl +++ b/drivers/mxc/amd-gpu/common/pm4_microcode.inl @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2010, QUALCOMM Incorporated. All rights reserved. +/* Copyright (c) 2008-2011, QUALCOMM Incorporated. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -26,12 +26,14 @@ * */ +// Microcode Source Version 20111020.a + #ifndef PM4_MICROCODE_H #define PM4_MICROCODE_H -#define PM4_MICROCODE_VERSION 300684 +#define PM4_MICROCODE_VERSION 422468 -#define PM4_MICROCODE_SIZE 768 +#define PM4_MICROCODE_SIZE 768 // Size of PM4 microcode in QWORD #ifdef _PRIMLIB_INCLUDE @@ -47,20 +49,20 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0xd9004800, 0x000 }, { 0x00000000, 0x00400000, 0x000 }, { 0x00000000, 0x34e00000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x0000ffff, 0xc0280a20, 0x000 }, { 0x00000000, 0x00294582, 0x000 }, { 0x00000000, 0xd9004800, 0x000 }, { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x0000ffff, 0xc0284620, 0x000 }, { 0x00000000, 0xd9004800, 0x000 }, { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a8 }, + { 0x00000000, 0x00600000, 0x2ac }, { 0x00000000, 0xc0200c00, 0x000 }, { 0x000021fc, 0x0029462c, 0x000 }, { 0x00000000, 0x00404803, 0x021 }, - { 0x00000000, 0x00600000, 0x2a8 }, + { 0x00000000, 0x00600000, 0x2ac }, { 0x00000000, 0xc0200000, 0x000 }, { 0x00000000, 0xc0200c00, 0x000 }, { 0x000021fc, 0x0029462c, 0x000 }, @@ -78,7 +80,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x0000000e, 0x00404811, 0x000 }, { 0x00000394, 0x00204411, 0x000 }, { 0x00000001, 0xc0404811, 0x000 }, - { 0x00000000, 0x00600000, 0x2a8 }, + { 0x00000000, 0x00600000, 0x2ac }, { 0x000021f9, 0x0029462c, 0x000 }, { 0x00000008, 0xc0210a20, 0x000 }, { 0x00000000, 0x14e00000, 0x02d }, @@ -88,53 +90,48 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x0000001b, 0x002f0222, 0x000 }, { 0x00000000, 0x0ce00000, 0x043 }, { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04a }, + { 0x00000000, 0x0ce00000, 0x045 }, { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x051 }, + { 0x00000000, 0x0ce00000, 0x047 }, { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x058 }, + { 0x00000000, 0x0ce00000, 0x049 }, { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x058 }, + { 0x00000000, 0x0ce00000, 0x049 }, { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x060 }, + { 0x00000000, 0x0ce00000, 0x05b }, { 0x000021f9, 0x0029462c, 0x000 }, { 0x00000000, 0xc0404802, 0x000 }, { 0x0000001f, 0x40280a20, 0x000 }, { 0x0000001b, 0x002f0222, 0x000 }, { 0x00000000, 0x0ce00000, 0x043 }, { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04a }, - { 0x00000000, 0x00400000, 0x051 }, + { 0x00000000, 0x0ce00000, 0x045 }, + { 0x00000000, 0x00400000, 0x047 }, { 0x0000001f, 0xc0210e20, 0x000 }, - { 0x00000612, 0x00204411, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x000021f9, 0x0029462c, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, + { 0x00000612, 0x00404411, 0x04c }, { 0x0000001e, 0xc0210e20, 0x000 }, - { 0x00000600, 0x00204411, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x000021f9, 0x0029462c, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, + { 0x00000600, 0x00404411, 0x04c }, { 0x0000001e, 0xc0210e20, 0x000 }, - { 0x00000605, 0x00204411, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x000021f9, 0x0029462c, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, + { 0x00000605, 0x00404411, 0x04c }, { 0x0000001f, 0x40280a20, 0x000 }, { 0x0000001f, 0xc0210e20, 0x000 }, { 0x0000060a, 0x00204411, 0x000 }, { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, { 0x000021f9, 0x0029462c, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000001f, 0xc0680a20, 0x2a8 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00600000, 0x130 }, + { 0x00000000, 0x002f0070, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000001, 0x00331e27, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ae00000, 0x054 }, + { 0x00000000, 0x00400000, 0x051 }, + { 0x0000001f, 0xc0680a20, 0x2ac }, { 0x000021f9, 0x0029462c, 0x000 }, { 0x00000000, 0x00404802, 0x000 }, { 0x8100ffff, 0x00204411, 0x000 }, @@ -142,24 +139,24 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00001fff, 0x40280a20, 0x000 }, { 0x80000000, 0x40280e20, 0x000 }, { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x2b2 }, + { 0x00040000, 0x00694622, 0x2b4 }, { 0x00000000, 0x00201410, 0x000 }, { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x06d }, - { 0x00000000, 0xc0401800, 0x070 }, + { 0x00000000, 0x0ae00000, 0x068 }, + { 0x00000000, 0xc0401800, 0x06b }, { 0x00001fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x2b2 }, + { 0x00040000, 0x00694626, 0x2b4 }, { 0x00000000, 0x00201810, 0x000 }, { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ae00000, 0x073 }, - { 0x00000000, 0xc0401c00, 0x076 }, + { 0x00000000, 0x0ae00000, 0x06e }, + { 0x00000000, 0xc0401c00, 0x071 }, { 0x00001fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x2b2 }, + { 0x00040000, 0x00694627, 0x2b4 }, { 0x00000000, 0x00201c10, 0x000 }, { 0x00000000, 0x00204402, 0x000 }, { 0x00000000, 0x002820c5, 0x000 }, { 0x00000000, 0x004948e8, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x00000010, 0x40210a20, 0x000 }, { 0x000000ff, 0x00280a22, 0x000 }, { 0x000007ff, 0x40280e20, 0x000 }, @@ -167,25 +164,25 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000005, 0xc0211220, 0x000 }, { 0x00080000, 0x00281224, 0x000 }, { 0x00000013, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x084 }, + { 0x00000000, 0x14c00000, 0x07f }, { 0xa100ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00204811, 0x000 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x088 }, + { 0x00000000, 0x0ae00000, 0x083 }, { 0x00000000, 0x0020162d, 0x000 }, - { 0x00004000, 0x00500e23, 0x097 }, + { 0x00004000, 0x00500e23, 0x092 }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x08c }, + { 0x00000000, 0x0ae00000, 0x087 }, { 0x00000001, 0x0020162d, 0x000 }, - { 0x00004800, 0x00500e23, 0x097 }, + { 0x00004800, 0x00500e23, 0x092 }, { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x090 }, + { 0x00000000, 0x0ae00000, 0x08b }, { 0x00000003, 0x0020162d, 0x000 }, - { 0x00004900, 0x00500e23, 0x097 }, + { 0x00004900, 0x00500e23, 0x092 }, { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x094 }, + { 0x00000000, 0x0ae00000, 0x08f }, { 0x00000002, 0x0020162d, 0x000 }, - { 0x00004908, 0x00500e23, 0x097 }, + { 0x00004908, 0x00500e23, 0x092 }, { 0x00000012, 0x0020162d, 0x000 }, { 0x00002000, 0x00300e23, 0x000 }, { 0x00000000, 0x00290d83, 0x000 }, @@ -200,7 +197,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x002948e5, 0x000 }, { 0x9300ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00404806, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x00000000, 0xc0201400, 0x000 }, { 0x0000001f, 0x00211a25, 0x000 }, @@ -209,31 +206,31 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000010, 0x00211225, 0x000 }, { 0x8300ffff, 0x00204411, 0x000 }, { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0ae }, + { 0x00000000, 0x0ae00000, 0x0a9 }, { 0x00000000, 0x00203622, 0x000 }, - { 0x00004000, 0x00504a23, 0x0bd }, + { 0x00004000, 0x00504a23, 0x0b8 }, { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b2 }, + { 0x00000000, 0x0ae00000, 0x0ad }, { 0x00000001, 0x00203622, 0x000 }, - { 0x00004800, 0x00504a23, 0x0bd }, + { 0x00004800, 0x00504a23, 0x0b8 }, { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b6 }, + { 0x00000000, 0x0ae00000, 0x0b1 }, { 0x00000003, 0x00203622, 0x000 }, - { 0x00004900, 0x00504a23, 0x0bd }, + { 0x00004900, 0x00504a23, 0x0b8 }, { 0x00000003, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0ba }, + { 0x00000000, 0x0ae00000, 0x0b5 }, { 0x00000002, 0x00203622, 0x000 }, - { 0x00004908, 0x00504a23, 0x0bd }, + { 0x00004908, 0x00504a23, 0x0b8 }, { 0x00000012, 0x00203622, 0x000 }, { 0x00000000, 0x00290d83, 0x000 }, { 0x00002000, 0x00304a23, 0x000 }, { 0x8400ffff, 0x00204411, 0x000 }, { 0x00000000, 0xc0204800, 0x000 }, { 0x00000000, 0x21000000, 0x000 }, - { 0x00000000, 0x00400000, 0x0a4 }, + { 0x00000000, 0x00400000, 0x09f }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, - { 0x00040578, 0x00604411, 0x2b2 }, + { 0x00040578, 0x00604411, 0x2b4 }, { 0x00000000, 0xc0400000, 0x000 }, { 0x00000000, 0xc0200c00, 0x000 }, { 0x00000000, 0xc0201000, 0x000 }, @@ -241,62 +238,62 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0xc0201800, 0x000 }, { 0x00007f00, 0x00280a21, 0x000 }, { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0cd }, + { 0x00000000, 0x0ce00000, 0x0c8 }, { 0x00000000, 0xc0201c00, 0x000 }, { 0x00000000, 0x17000000, 0x000 }, { 0x00000010, 0x00280a23, 0x000 }, { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000000, 0x0ce00000, 0x0d0 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x2b2 }, - { 0x00000000, 0x00400000, 0x0d6 }, - { 0x00000000, 0x00600000, 0x135 }, + { 0x00040000, 0x00694624, 0x2b4 }, + { 0x00000000, 0x00400000, 0x0d1 }, + { 0x00000000, 0x00600000, 0x130 }, { 0x00000000, 0x002820d0, 0x000 }, { 0x00000007, 0x00280a23, 0x000 }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0dd }, + { 0x00000000, 0x0ae00000, 0x0d8 }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x04e00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, + { 0x00000000, 0x04e00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0e2 }, + { 0x00000000, 0x0ae00000, 0x0dd }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x02e00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, + { 0x00000000, 0x02e00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0e7 }, + { 0x00000000, 0x0ae00000, 0x0e2 }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, + { 0x00000000, 0x0ce00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0ec }, + { 0x00000000, 0x0ae00000, 0x0e7 }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, - { 0x00000005, 0x002f0222, 0x000 }, { 0x00000000, 0x0ae00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0ec }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x06e00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, + { 0x00000000, 0x06e00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0f6 }, + { 0x00000000, 0x0ae00000, 0x0f1 }, { 0x00000000, 0x002f00a8, 0x000 }, - { 0x00000000, 0x08e00000, 0x0f6 }, - { 0x00000000, 0x00400000, 0x0fd }, + { 0x00000000, 0x08e00000, 0x0f1 }, + { 0x00000000, 0x00400000, 0x0f8 }, { 0x00007f00, 0x00280a21, 0x000 }, { 0x00004500, 0x002f0222, 0x000 }, { 0x00000000, 0x0ae00000, 0x000 }, { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14e00000, 0x11b }, + { 0x00000000, 0x14e00000, 0x116 }, { 0x00000000, 0xc0204400, 0x000 }, { 0x00000000, 0xc0404800, 0x000 }, { 0x00007f00, 0x00280a21, 0x000 }, { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x102 }, + { 0x00000000, 0x0ae00000, 0x0fd }, { 0x00000000, 0xc0200000, 0x000 }, { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c07, 0x0cd }, + { 0x00000000, 0x00404c07, 0x0c8 }, { 0x00000000, 0xc0201000, 0x000 }, { 0x00000000, 0xc0201400, 0x000 }, { 0x00000000, 0xc0201800, 0x000 }, @@ -304,11 +301,11 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x17000000, 0x000 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x2b2 }, + { 0x00040000, 0x00694624, 0x2b4 }, { 0x00000000, 0x002820d0, 0x000 }, { 0x00000000, 0x002f00a8, 0x000 }, { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00404c07, 0x107 }, + { 0x00000000, 0x00404c07, 0x102 }, { 0x00000000, 0xc0201000, 0x000 }, { 0x00000000, 0xc0201400, 0x000 }, { 0x00000000, 0xc0201800, 0x000 }, @@ -316,11 +313,11 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x17000000, 0x000 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x2b2 }, + { 0x00040000, 0x00694624, 0x2b4 }, { 0x00000000, 0x002820d0, 0x000 }, { 0x00000000, 0x002f00a8, 0x000 }, { 0x00000000, 0x06e00000, 0x000 }, - { 0x00000000, 0x00404c07, 0x113 }, + { 0x00000000, 0x00404c07, 0x10e }, { 0x0000060d, 0x00204411, 0x000 }, { 0x00000000, 0xc0204800, 0x000 }, { 0x0000860e, 0x00204411, 0x000 }, @@ -335,13 +332,13 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000001, 0x00204811, 0x000 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x00007fff, 0x00281a22, 0x000 }, - { 0x00040000, 0x00694626, 0x2b2 }, + { 0x00040000, 0x00694626, 0x2b4 }, { 0x00000000, 0x00200c10, 0x000 }, { 0x00000000, 0xc0201000, 0x000 }, { 0x80000000, 0x00281a22, 0x000 }, { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0ce00000, 0x132 }, - { 0x00000000, 0x00600000, 0x135 }, + { 0x00000000, 0x0ce00000, 0x12d }, + { 0x00000000, 0x00600000, 0x130 }, { 0x00000000, 0x00201c10, 0x000 }, { 0x00000000, 0x00300c67, 0x000 }, { 0x0000060d, 0x00204411, 0x000 }, @@ -353,10 +350,10 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00204811, 0x000 }, { 0x000001ea, 0x00204411, 0x000 }, { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x1ac00000, 0x13b }, + { 0x00000000, 0x1ac00000, 0x136 }, { 0x9e00ffff, 0x00204411, 0x000 }, { 0xdeadbeef, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x13e }, + { 0x00000000, 0x1ae00000, 0x139 }, { 0xa400ffff, 0x00204411, 0x000 }, { 0x00000000, 0x0080480b, 0x000 }, { 0x000001f3, 0x00204411, 0x000 }, @@ -405,28 +402,28 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000001, 0x00303e2f, 0x000 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x172 }, + { 0x00000000, 0x0ce00000, 0x16d }, { 0x00000000, 0xd9000000, 0x000 }, { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000002, 0x00204811, 0x000 }, { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ae00000, 0x175 }, + { 0x00000000, 0x0ae00000, 0x170 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x00000009, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x17d }, - { 0x00000000, 0x00600000, 0x2af }, + { 0x00000000, 0x14c00000, 0x178 }, + { 0x00000000, 0x00600000, 0x2aa }, { 0x00000000, 0x00200c11, 0x000 }, { 0x00000016, 0x00203623, 0x000 }, { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x180 }, + { 0x00000000, 0x14c00000, 0x17b }, { 0x00000000, 0xc0200000, 0x000 }, { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x183 }, + { 0x00000000, 0x14c00000, 0x17e }, { 0x00000000, 0xc0200000, 0x000 }, { 0x00000002, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x18d }, + { 0x00000000, 0x14c00000, 0x188 }, { 0x00000004, 0xc0203620, 0x000 }, { 0x00000005, 0xc0203620, 0x000 }, { 0x00000006, 0xc0203620, 0x000 }, @@ -436,7 +433,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x0000000a, 0xc0203620, 0x000 }, { 0x0000000b, 0xc0203620, 0x000 }, { 0x00000003, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b5 }, + { 0x00000000, 0x14c00000, 0x1b0 }, { 0x00000000, 0xc0200c00, 0x000 }, { 0x8c00ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00204803, 0x000 }, @@ -476,24 +473,24 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000003, 0x00384a27, 0x000 }, { 0x00300000, 0x00293a2e, 0x000 }, { 0x00000004, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1bd }, + { 0x00000000, 0x14c00000, 0x1b8 }, { 0xa300ffff, 0x00204411, 0x000 }, { 0x00000000, 0x40204800, 0x000 }, { 0x0000000a, 0xc0220e20, 0x000 }, { 0x00000011, 0x00203623, 0x000 }, { 0x000021f4, 0x00204411, 0x000 }, - { 0x0000000a, 0x00614a2c, 0x2af }, + { 0x0000000a, 0x00614a2c, 0x2aa }, { 0x00000005, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1c0 }, + { 0x00000000, 0x14c00000, 0x1bb }, { 0x00000000, 0xc0200000, 0x000 }, { 0x00000006, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1c6 }, + { 0x00000000, 0x14c00000, 0x1c1 }, { 0x9c00ffff, 0x00204411, 0x000 }, { 0x0000001f, 0x40214a20, 0x000 }, { 0x9600ffff, 0x00204411, 0x000 }, { 0x00000000, 0xc0204800, 0x000 }, { 0x00000007, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1d0 }, + { 0x00000000, 0x14c00000, 0x1cb }, { 0x3fffffff, 0x00283a2e, 0x000 }, { 0xc0000000, 0x40280e20, 0x000 }, { 0x00000000, 0x0029386e, 0x000 }, @@ -503,7 +500,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0xc0202c00, 0x000 }, { 0x00000000, 0x0020480b, 0x000 }, { 0x00000008, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x1dc }, + { 0x00000000, 0x14c00000, 0x1d7 }, { 0x00000000, 0xc0200c00, 0x000 }, { 0x00000013, 0x00203623, 0x000 }, { 0x00000015, 0x00203623, 0x000 }, @@ -515,7 +512,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0xefffffff, 0x00283a2e, 0x000 }, { 0x00000000, 0x0029386e, 0x000 }, { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, + { 0x00000000, 0x00600000, 0x287 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x0000001f, 0x00210e22, 0x000 }, { 0x00000000, 0x14e00000, 0x000 }, @@ -529,46 +526,46 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x8400ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00204803, 0x000 }, { 0x00000000, 0x21000000, 0x000 }, - { 0x00000000, 0x00400000, 0x1de }, + { 0x00000000, 0x00400000, 0x1d9 }, { 0x8200ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, { 0x00000000, 0xc0200800, 0x000 }, { 0x00003fff, 0x40280e20, 0x000 }, { 0x00000010, 0xc0211220, 0x000 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x1fb }, - { 0x00000000, 0x2ae00000, 0x205 }, + { 0x00000000, 0x0ae00000, 0x1f6 }, + { 0x00000000, 0x2ae00000, 0x200 }, { 0x20000080, 0x00281e2e, 0x000 }, { 0x00000080, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000000, 0x00401c0c, 0x1f9 }, + { 0x00000000, 0x0ce00000, 0x1f3 }, + { 0x00000000, 0x00401c0c, 0x1f4 }, { 0x00000010, 0x00201e2d, 0x000 }, { 0x000021f9, 0x00294627, 0x000 }, - { 0x00000000, 0x00404811, 0x205 }, + { 0x00000000, 0x00404811, 0x200 }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x23a }, - { 0x00000000, 0x28e00000, 0x205 }, + { 0x00000000, 0x0ae00000, 0x235 }, + { 0x00000000, 0x28e00000, 0x200 }, { 0x00800080, 0x00281e2e, 0x000 }, { 0x00000080, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x202 }, - { 0x00000000, 0x00401c0c, 0x203 }, + { 0x00000000, 0x0ce00000, 0x1fd }, + { 0x00000000, 0x00401c0c, 0x1fe }, { 0x00000010, 0x00201e2d, 0x000 }, { 0x000021f9, 0x00294627, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x20c }, + { 0x00000000, 0x0ae00000, 0x207 }, { 0x00000003, 0x00204811, 0x000 }, { 0x0000000c, 0x0020162d, 0x000 }, { 0x0000000d, 0x00201a2d, 0x000 }, - { 0xffdfffff, 0x00483a2e, 0x210 }, + { 0xffdfffff, 0x00483a2e, 0x20b }, { 0x00000004, 0x00204811, 0x000 }, { 0x0000000e, 0x0020162d, 0x000 }, { 0x0000000f, 0x00201a2d, 0x000 }, { 0xffefffff, 0x00283a2e, 0x000 }, { 0x00000000, 0x00201c10, 0x000 }, { 0x00000000, 0x002f0067, 0x000 }, - { 0x00000000, 0x04e00000, 0x205 }, + { 0x00000000, 0x04e00000, 0x200 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000006, 0x00204811, 0x000 }, { 0x8300ffff, 0x00204411, 0x000 }, @@ -578,10 +575,10 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x8400ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00204803, 0x000 }, { 0x00000000, 0x21000000, 0x000 }, - { 0x00000000, 0x00601010, 0x28c }, + { 0x00000000, 0x00601010, 0x287 }, { 0x0000000c, 0x00221e24, 0x000 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x22d }, + { 0x00000000, 0x0ae00000, 0x228 }, { 0x20000000, 0x00293a2e, 0x000 }, { 0x000021f7, 0x0029462c, 0x000 }, { 0x00000000, 0x002948c7, 0x000 }, @@ -594,7 +591,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00204803, 0x000 }, { 0x00000000, 0x23000000, 0x000 }, { 0x8d00ffff, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x240 }, + { 0x00000000, 0x00404803, 0x23b }, { 0x00800000, 0x00293a2e, 0x000 }, { 0x000021f6, 0x0029462c, 0x000 }, { 0x00000000, 0x002948c7, 0x000 }, @@ -607,7 +604,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00204803, 0x000 }, { 0x00000000, 0x25000000, 0x000 }, { 0x8e00ffff, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x240 }, + { 0x00000000, 0x00404803, 0x23b }, { 0x8300ffff, 0x00204411, 0x000 }, { 0x00000003, 0x00381224, 0x000 }, { 0x00005000, 0x00304a24, 0x000 }, @@ -621,37 +618,37 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000001, 0x00204811, 0x000 }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24a }, + { 0x00000000, 0x0ae00000, 0x245 }, { 0x000021f6, 0x0029122c, 0x000 }, - { 0x00040000, 0x00494624, 0x24c }, + { 0x00040000, 0x00494624, 0x247 }, { 0x000021f7, 0x0029122c, 0x000 }, { 0x00040000, 0x00294624, 0x000 }, - { 0x00000000, 0x00600000, 0x2b2 }, + { 0x00000000, 0x00600000, 0x2b4 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x252 }, + { 0x00000000, 0x0ce00000, 0x24d }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x252 }, - { 0x00000000, 0x00481630, 0x258 }, + { 0x00000000, 0x0ce00000, 0x24d }, + { 0x00000000, 0x00481630, 0x253 }, { 0x00000fff, 0x00281630, 0x000 }, { 0x0000000c, 0x00211a30, 0x000 }, { 0x00000fff, 0x00281a26, 0x000 }, { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0ae00000, 0x258 }, + { 0x00000000, 0x0ae00000, 0x253 }, { 0x00000000, 0xc0400000, 0x000 }, - { 0x00040d02, 0x00604411, 0x2b2 }, + { 0x00040d02, 0x00604411, 0x2b4 }, { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x25d }, + { 0x00000000, 0x0ae00000, 0x258 }, { 0x00000010, 0x00211e30, 0x000 }, - { 0x00000fff, 0x00482630, 0x267 }, + { 0x00000fff, 0x00482630, 0x262 }, { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x261 }, + { 0x00000000, 0x0ae00000, 0x25c }, { 0x00000fff, 0x00281e30, 0x000 }, - { 0x00000200, 0x00402411, 0x267 }, + { 0x00000200, 0x00402411, 0x262 }, { 0x00000000, 0x00281e30, 0x000 }, { 0x00000010, 0x00212630, 0x000 }, { 0x00000010, 0x00211a30, 0x000 }, { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0ae00000, 0x258 }, + { 0x00000000, 0x0ae00000, 0x253 }, { 0x00000000, 0xc0400000, 0x000 }, { 0x00000003, 0x00381625, 0x000 }, { 0x00000003, 0x00381a26, 0x000 }, @@ -662,13 +659,13 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0xc0204800, 0x000 }, { 0x00000000, 0x00204806, 0x000 }, { 0x00005000, 0x00302225, 0x000 }, - { 0x00040000, 0x00694628, 0x2b2 }, + { 0x00040000, 0x00694628, 0x2b4 }, { 0x00000001, 0x00302228, 0x000 }, { 0x00000000, 0x00202810, 0x000 }, - { 0x00040000, 0x00694628, 0x2b2 }, + { 0x00040000, 0x00694628, 0x2b4 }, { 0x00000001, 0x00302228, 0x000 }, { 0x00000000, 0x00200810, 0x000 }, - { 0x00040000, 0x00694628, 0x2b2 }, + { 0x00040000, 0x00694628, 0x2b4 }, { 0x00000001, 0x00302228, 0x000 }, { 0x00000000, 0x00201410, 0x000 }, { 0x0000060d, 0x00204411, 0x000 }, @@ -678,35 +675,42 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00204802, 0x000 }, { 0x00000000, 0x00204805, 0x000 }, { 0x00000000, 0x002f0128, 0x000 }, - { 0x00000000, 0x0ae00000, 0x282 }, + { 0x00000000, 0x0ae00000, 0x27d }, { 0x00005000, 0x00302227, 0x000 }, { 0x0000000c, 0x00300e23, 0x000 }, { 0x00000003, 0x00331a26, 0x000 }, { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0ae00000, 0x270 }, + { 0x00000000, 0x0ae00000, 0x26b }, { 0x00000000, 0x00400000, 0x000 }, { 0x000001f3, 0x00204411, 0x000 }, { 0x04000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x289 }, - { 0x00000000, 0xc0600000, 0x28c }, + { 0x00000000, 0x00400000, 0x284 }, + { 0x00000000, 0xc0600000, 0x287 }, { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0x0ec00000, 0x28e }, + { 0x00000000, 0x0ec00000, 0x289 }, { 0x00000000, 0x00800000, 0x000 }, { 0x000021f9, 0x0029462c, 0x000 }, { 0x00000005, 0x00204811, 0x000 }, + { 0x8100ffff, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x0000000a, 0x0021262c, 0x000 }, + { 0x00000000, 0x00210130, 0x000 }, + { 0x00000000, 0x14c00000, 0x292 }, + { 0xa500ffff, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x28e }, { 0x00000000, 0x0020280c, 0x000 }, { 0x00000011, 0x0020262d, 0x000 }, { 0x00000000, 0x002f012c, 0x000 }, - { 0x00000000, 0x0ae00000, 0x295 }, - { 0x00000000, 0x00403011, 0x296 }, + { 0x00000000, 0x0ae00000, 0x297 }, + { 0x00000000, 0x00403011, 0x298 }, { 0x00000400, 0x0030322c, 0x000 }, { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000002, 0x00204811, 0x000 }, { 0x0000000a, 0x0021262c, 0x000 }, { 0x00000000, 0x00210130, 0x000 }, - { 0x00000000, 0x14c00000, 0x29d }, + { 0x00000000, 0x14c00000, 0x29f }, { 0xa500ffff, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x299 }, + { 0x00000001, 0x00404811, 0x29b }, { 0xa500ffff, 0x00204411, 0x000 }, { 0x00000000, 0x00204811, 0x000 }, { 0x000021f4, 0x0029462c, 0x000 }, @@ -718,6 +722,8 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00210130, 0x000 }, { 0xdf7fffff, 0x00283a2e, 0x000 }, { 0x00000010, 0x0080362a, 0x000 }, + { 0x00000000, 0x00203011, 0x000 }, + { 0x00000010, 0x0080362c, 0x000 }, { 0x9700ffff, 0x00204411, 0x000 }, { 0x00000000, 0x0020480c, 0x000 }, { 0xa200ffff, 0x00204411, 0x000 }, @@ -725,13 +731,11 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x8100ffff, 0x00204411, 0x000 }, { 0x00000002, 0x00204811, 0x000 }, { 0x00000000, 0x00810130, 0x000 }, - { 0x00000000, 0x00203011, 0x000 }, - { 0x00000010, 0x0080362c, 0x000 }, { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x2b2 }, + { 0x00000000, 0x1ac00000, 0x2b4 }, { 0x9f00ffff, 0x00204411, 0x000 }, { 0xdeadbeef, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x2b5 }, + { 0x00000000, 0x1ae00000, 0x2b7 }, { 0x00000000, 0x00800000, 0x000 }, { 0x00000000, 0x00000000, 0x000 }, { 0x00000000, 0x00000000, 0x000 }, @@ -776,28 +780,26 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00000000, 0x00000000, 0x000 }, { 0x00000000, 0x00000000, 0x000 }, { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00020143, 0x00020002, 0x000 }, + { 0x0002013e, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, - { 0x00020002, 0x01dd0002, 0x000 }, - { 0x006301ee, 0x00280012, 0x000 }, + { 0x00020002, 0x01d80002, 0x000 }, + { 0x005e01e9, 0x00280012, 0x000 }, { 0x00020002, 0x00020026, 0x000 }, - { 0x00020002, 0x01ec0002, 0x000 }, - { 0x00790242, 0x00020002, 0x000 }, + { 0x00020002, 0x01e70002, 0x000 }, + { 0x0074023d, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, { 0x00200012, 0x00020016, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, - { 0x011b00c5, 0x00020125, 0x000 }, - { 0x00020141, 0x00020002, 0x000 }, - { 0x00c50002, 0x0143002e, 0x000 }, - { 0x00a2016b, 0x00020145, 0x000 }, - { 0x00020002, 0x01200002, 0x000 }, - { 0x00020002, 0x010f0103, 0x000 }, + { 0x011600c0, 0x00020120, 0x000 }, + { 0x0002013c, 0x00020002, 0x000 }, + { 0x00c00002, 0x013e002e, 0x000 }, + { 0x009d0166, 0x00020140, 0x000 }, + { 0x00020002, 0x011b0002, 0x000 }, + { 0x00020002, 0x010a00fe, 0x000 }, { 0x00090002, 0x000e000e, 0x000 }, - { 0x0058003d, 0x00600002, 0x000 }, - { 0x000200c1, 0x0002028a, 0x000 }, + { 0x0049003d, 0x005b0002, 0x000 }, + { 0x000200bc, 0x00020285, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, @@ -805,7 +807,7 @@ uint32 aPM4_Microcode[PM4_MICROCODE_SIZE][3]={ { 0x00020002, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, { 0x00020002, 0x00020002, 0x000 }, - { 0x000502b1, 0x00020008, 0x000 }, + { 0x000502b3, 0x00020008, 0x000 }, }; #endif diff --git a/drivers/mxc/amd-gpu/include/gsl_buildconfig.h b/drivers/mxc/amd-gpu/include/gsl_buildconfig.h index 4e6be4da7dc4..b5f852951103 100644 --- a/drivers/mxc/amd-gpu/include/gsl_buildconfig.h +++ b/drivers/mxc/amd-gpu/include/gsl_buildconfig.h @@ -27,7 +27,7 @@ */ /* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. */ #ifndef __GSL__BUILDCONFIG_H @@ -49,7 +49,7 @@ /* #define GSL_MMU_PAGETABLE_PERPROCESS */ -#define GSL_CALLER_PROCESS_MAX 10 +#define GSL_CALLER_PROCESS_MAX 64 #define GSL_SHMEM_MAX_APERTURES 3 #endif /* __GSL__BUILDCONFIG_H */ diff --git a/drivers/mxc/amd-gpu/include/gsl_halconfig.h b/drivers/mxc/amd-gpu/include/gsl_halconfig.h index 363474b7a6bb..a023a9409dac 100644 --- a/drivers/mxc/amd-gpu/include/gsl_halconfig.h +++ b/drivers/mxc/amd-gpu/include/gsl_halconfig.h @@ -27,7 +27,7 @@ */ /* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. */ #ifndef __GSL_HALCONFIG_H @@ -38,7 +38,7 @@ #define GSL_HAL_SIZE_REG_G12 0x00001000 /* 4KB */ -#define GSL_HAL_SHMEM_SIZE_EMEM1_MMU 0x01800000 /* 24MB */ +#define GSL_HAL_SHMEM_SIZE_EMEM1_MMU 0x08000000 /* 128MB */ #define GSL_HAL_SHMEM_SIZE_EMEM2_MMU 0x00400000 /* 4MB */ #define GSL_HAL_SHMEM_SIZE_PHYS_MMU 0x00400000 /* 4MB */ diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hal.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hal.c index 51270ada4d36..45740b53d9b7 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hal.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hal.c @@ -1,5 +1,5 @@ /* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. - * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2008-2012 Freescale Semiconductor, 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 and @@ -17,10 +17,6 @@ * */ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - #include "gsl_hal.h" #include "gsl_halconfig.h" #include "gsl_linux_map.h" @@ -49,6 +45,7 @@ extern int gmem_size; extern phys_addr_t gpu_reserved_mem; extern int gpu_reserved_mem_size; extern int gpu_2d_irq, gpu_3d_irq; +extern int enable_mmu; KGSLHAL_API int @@ -121,8 +118,7 @@ kgsl_hal_init(void) hal->has_z160 = 0; } - /* there is still some problem to enable mmu currently */ - gsl_driver.enable_mmu = 0; + gsl_driver.enable_mmu = enable_mmu; /* setup register space */ if (hal->has_z430) { diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h index 305b2ee9066d..96abace9b736 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h @@ -43,8 +43,6 @@ kgsl_hwaccess_memread(void *dst, unsigned int gpubase, unsigned int gpuoffset, u if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { gsl_linux_map_read(dst, gpubase+gpuoffset, sizebytes, touserspace); } else { - mb(); - dsb(); if (touserspace) { if (copy_to_user(dst, (void *)(gpubase + gpuoffset), sizebytes)) @@ -56,8 +54,6 @@ kgsl_hwaccess_memread(void *dst, unsigned int gpubase, unsigned int gpuoffset, u { kos_memcpy(dst, (void *) (gpubase + gpuoffset), sizebytes); } - mb(); - dsb(); } } @@ -69,8 +65,6 @@ kgsl_hwaccess_memwrite(unsigned int gpubase, unsigned int gpuoffset, void *src, if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { gsl_linux_map_write(src, gpubase+gpuoffset, sizebytes, fromuserspace); } else { - mb(); - dsb(); if (fromuserspace) { if (copy_from_user((void *)(gpubase + gpuoffset), src, sizebytes)) @@ -82,8 +76,6 @@ kgsl_hwaccess_memwrite(unsigned int gpubase, unsigned int gpuoffset, void *src, { kos_memcpy((void *)(gpubase + gpuoffset), src, sizebytes); } - mb(); - dsb(); } } @@ -95,11 +87,7 @@ kgsl_hwaccess_memset(unsigned int gpubase, unsigned int gpuoffset, unsigned int if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { gsl_linux_map_set(gpuoffset+gpubase, value, sizebytes); } else { - mb(); - dsb(); kos_memset((void *)(gpubase + gpuoffset), value, sizebytes); - mb(); - dsb(); } } @@ -115,11 +103,7 @@ kgsl_hwaccess_regread(gsl_deviceid_t device_id, unsigned int gpubase, unsigned i reg = (unsigned int *)(gpubase + (offsetwords << 2)); - mb(); - dsb(); - *data = __raw_readl(reg); - mb(); - dsb(); + *data = readl(reg); } //---------------------------------------------------------------------------- @@ -133,10 +117,6 @@ kgsl_hwaccess_regwrite(gsl_deviceid_t device_id, unsigned int gpubase, unsigned (void) device_id; reg = (unsigned int *)(gpubase + (offsetwords << 2)); - mb(); - dsb(); - __raw_writel(data, reg); - mb(); - dsb(); + writel(data, reg); } #endif // __GSL_HWACCESS_WINCE_MX51_H diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c index b67404150e10..2e6bc55e88fe 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c @@ -1,5 +1,5 @@ /* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. - * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2008-2012 Freescale Semiconductor, 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 and @@ -40,6 +40,7 @@ #include <linux/uaccess.h> #include <mach/mxc_gpu.h> +#include <linux/fsl_devices.h> int gpu_2d_irq, gpu_3d_irq; @@ -51,6 +52,7 @@ int gmem_size; phys_addr_t gpu_reserved_mem; int gpu_reserved_mem_size; int z160_version; +int enable_mmu; static ssize_t gsl_kmod_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr); static ssize_t gsl_kmod_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr); @@ -769,14 +771,15 @@ static int gpu_probe(struct platform_device *pdev) int i; struct resource *res; struct device *dev; - struct mxc_gpu_platform_data *pdata; + struct mxc_gpu_platform_data *gpu_data = NULL; - pdata = pdev->dev.platform_data; - if (pdata) { - z160_version = pdata->z160_revision; - gpu_reserved_mem = pdata->reserved_mem_base; - gpu_reserved_mem_size = pdata->reserved_mem_size; - } + gpu_data = (struct mxc_gpu_platform_data *)pdev->dev.platform_data; + + if (gpu_data == NULL) + return 0; + + z160_version = gpu_data->z160_revision; + enable_mmu = gpu_data->enable_mmu; for(i = 0; i < 2; i++){ res = platform_get_resource(pdev, IORESOURCE_IRQ, i); @@ -795,8 +798,8 @@ static int gpu_probe(struct platform_device *pdev) } } - for (i = 0; i < 3; i++) { - res = platform_get_resource(pdev, IORESOURCE_MEM, i); + for (i = 0; i < 4; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) { gpu_2d_regbase = 0; gpu_2d_regsize = 0; @@ -807,14 +810,17 @@ static int gpu_probe(struct platform_device *pdev) gpu_reserved_mem_size = 0; break; }else{ - if(strcmp(res->name, "gpu_2d_registers") == 0){ - gpu_2d_regbase = res->start; - gpu_2d_regsize = res->end - res->start + 1; - }else if(strcmp(res->name, "gpu_3d_registers") == 0){ - gpu_3d_regbase = res->start; - gpu_3d_regsize = res->end - res->start + 1; - }else if(strcmp(res->name, "gpu_graphics_mem") == 0){ - gmem_size = res->end - res->start + 1; + if (strcmp(res->name, "gpu_2d_registers") == 0) { + gpu_2d_regbase = res->start; + gpu_2d_regsize = res->end - res->start + 1; + } else if (strcmp(res->name, "gpu_3d_registers") == 0) { + gpu_3d_regbase = res->start; + gpu_3d_regsize = res->end - res->start + 1; + } else if (strcmp(res->name, "gpu_graphics_mem") == 0) { + gmem_size = res->end - res->start + 1; + } else if (strcmp(res->name, "gpu_reserved_mem") == 0) { + gpu_reserved_mem = res->start; + gpu_reserved_mem_size = res->end - res->start + 1; } } } diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod_cleanup.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod_cleanup.c index 3685a5756baf..911469b720d7 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod_cleanup.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod_cleanup.c @@ -173,10 +173,13 @@ int del_all_memblocks_from_allocated_list(struct file *fd) printk(KERN_INFO "Not all allocated memory blocks were freed. Doing it now.\n"); list_for_each_entry_safe(cursor, next, head, node) { - printk(KERN_INFO "Freeing list entry #%u, gpuaddr=%x\n", (u32)cursor->allocation_number, cursor->allocated_block.gpuaddr); - kgsl_sharedmem_free(&cursor->allocated_block); - list_del(&cursor->node); - kfree(cursor); + printk(KERN_DEBUG "Freeing list entry #%u, gpuaddr=%x\n", + (u32)cursor->allocation_number, + cursor->allocated_block.gpuaddr); + + kgsl_sharedmem_free(&cursor->allocated_block); + list_del(&cursor->node); + kfree(cursor); } } diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.c index 7fee7b814411..3c1e02e5bc42 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.c @@ -61,7 +61,7 @@ void *gsl_linux_map_alloc(unsigned int gpu_addr, unsigned int size) } } - va = __vmalloc(size, GFP_KERNEL, pgprot_noncached(pgprot_kernel)); + va = __vmalloc(size, GFP_KERNEL, pgprot_writecombine(pgprot_kernel)); if(va == NULL){ mutex_unlock(&gsl_linux_map_mutex); return NULL; diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/misc.c b/drivers/mxc/amd-gpu/platform/hal/linux/misc.c index b3a4582bb156..db7b8cf3a2d1 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/misc.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -38,9 +38,9 @@ typedef struct _gsl_autogate_t { } gsl_autogate_t; static gsl_autogate_t *g_autogate[2]; -static DEFINE_SEMAPHORE(sem_dev); +static DEFINE_MUTEX(sem_dev); -#define KGSL_DEVICE_IDLE_TIMEOUT 5000 /* unit ms */ +#define KGSL_DEVICE_IDLE_TIMEOUT 2000 /* unit ms */ static void clk_disable_task(struct work_struct *work) { @@ -79,10 +79,10 @@ static int _kgsl_device_active(gsl_device_t *dev, int all) int index; index = autogate->dev->id == GSL_DEVICE_G12 ? GSL_DEVICE_YAMATO - 1 : GSL_DEVICE_G12 - 1; - down(&sem_dev); + mutex_lock(&sem_dev); if (g_autogate[index]) _kgsl_device_active(g_autogate[index]->dev, 0); - up(&sem_dev); + mutex_unlock(&sem_dev); } return 0; } @@ -99,7 +99,6 @@ static void kgsl_device_inactive(unsigned long data) // printk(KERN_ERR "%s:%d id %d active %d\n", __func__, __LINE__, autogate->dev->id, autogate->active); del_timer(&autogate->timer); spin_lock_irqsave(&autogate->lock, flags); - WARN(!autogate->active, "GPU Device %d is already inactive\n", autogate->dev->id); if (autogate->active) { autogate->active = 0; autogate->pending = 1; @@ -137,7 +136,7 @@ int kgsl_device_autogate_init(gsl_device_t *dev) printk(KERN_ERR "%s: out of memory!\n", __func__); return -ENOMEM; } - down(&sem_dev); + mutex_lock(&sem_dev); autogate->dev = dev; autogate->active = 1; spin_lock_init(&autogate->lock); @@ -150,7 +149,7 @@ int kgsl_device_autogate_init(gsl_device_t *dev) INIT_WORK(&autogate->dis_task, clk_disable_task); dev->autogate = autogate; g_autogate[dev->id - 1] = autogate; - up(&sem_dev); + mutex_unlock(&sem_dev); return 0; } @@ -159,13 +158,13 @@ void kgsl_device_autogate_exit(gsl_device_t *dev) gsl_autogate_t *autogate = dev->autogate; // printk(KERN_ERR "%s:%d id %d active %d\n", __func__, __LINE__, dev->id, autogate->active); - down(&sem_dev); + mutex_lock(&sem_dev); del_timer_sync(&autogate->timer); if (!autogate->active) kgsl_clock(autogate->dev->id, 1); flush_work(&autogate->dis_task); g_autogate[dev->id - 1] = NULL; - up(&sem_dev); + mutex_unlock(&sem_dev); kfree(autogate); dev->autogate = NULL; } diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index 877f2e5a2a9f..17bc2e53a418 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -233,6 +233,10 @@ static int __devinit ipu_probe(struct platform_device *pdev) ipu->dev = &pdev->dev; + if (!plat_data->bypass_reset) + if (plat_data->init) + plat_data->init(pdev->id); + ipu->irq_err = platform_get_irq(pdev, 0); ipu->irq_sync = platform_get_irq(pdev, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -320,9 +324,6 @@ static int __devinit ipu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ipu); if (!plat_data->bypass_reset) { - if (plat_data->init) - plat_data->init(pdev->id); - ipu_reset(ipu); ipu_disp_init(ipu); diff --git a/drivers/mxc/pmic/core/pmic_core_i2c.c b/drivers/mxc/pmic/core/pmic_core_i2c.c index 09172b387b0e..0bfad1ac5414 100644 --- a/drivers/mxc/pmic/core/pmic_core_i2c.c +++ b/drivers/mxc/pmic/core/pmic_core_i2c.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -256,7 +256,7 @@ static int __devinit pmic_probe(struct i2c_client *client, /* Set and install PMIC IRQ handler */ - set_irq_type(pmic_irq, IRQF_TRIGGER_HIGH); + irq_set_irq_type(pmic_irq, IRQF_TRIGGER_HIGH); ret = request_irq(pmic_irq, pmic_irq_handler, 0, "PMIC_IRQ", diff --git a/drivers/mxc/pmic/core/pmic_core_spi.c b/drivers/mxc/pmic/core/pmic_core_spi.c index f02b42749791..4c7f541f5d0b 100644 --- a/drivers/mxc/pmic/core/pmic_core_spi.c +++ b/drivers/mxc/pmic/core/pmic_core_spi.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -198,7 +198,7 @@ static int __devinit pmic_probe(struct spi_device *spi) } /* Set and install PMIC IRQ handler */ - set_irq_type(spi->irq, IRQF_TRIGGER_HIGH); + irq_set_irq_type(spi->irq, IRQF_TRIGGER_HIGH); ret = request_irq(spi->irq, pmic_irq_handler, 0, "PMIC_IRQ", 0); if (ret) { kfree(spi_get_drvdata(spi)); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 86e4ea3404b3..879d115db147 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -19,7 +19,7 @@ * Copyright (c) 2004-2006 Macq Electronique SA. * * Support for FEC IEEE 1588. - * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Freescale Semiconductor, Inc. */ #include <linux/module.h> @@ -59,6 +59,7 @@ #if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) #define FEC_ALIGNMENT 0xf +#define FEC_RX_FIFO_BR 0x480 #else #define FEC_ALIGNMENT 0x3 #endif @@ -1581,6 +1582,11 @@ fec_restart(struct net_device *dev, int duplex) writel(0, fep->hwp + FEC_HASH_TABLE_LOW); #endif + /* FIXME: adjust RX FIFO size for performance*/ +#ifdef CONFIG_ARCH_MX53 + writel(FEC_RX_FIFO_BR, fep->hwp + FEC_R_FSTART); +#endif + /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index a24653787d1d..559d48ba9db8 100755 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -149,6 +149,13 @@ config BATTERY_DA9030 Say Y here to enable support for batteries charger integrated into DA9030 PMIC. +config BATTERY_MAX17085 + tristate "Maxim MAX17085 charger" + depends on PMIC_DA9052 && SENSORS_DA9052 + help + Say Y to include support for the battery on the MAX17085. This + is dependent on DA9052 sensor. + config BATTERY_MAX17040 tristate "Maxim MAX17040 Fuel Gauge" depends on I2C diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 1f359ba8a03c..845eb4fb213c 100755 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -37,4 +37,5 @@ obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o +obj-$(CONFIG_BATTERY_MAX17085) += max17085_battery.o obj-$(CONFIG_SABRESD_MAX8903) += sabresd_battery.o diff --git a/drivers/power/max17085_battery.c b/drivers/power/max17085_battery.c new file mode 100644 index 000000000000..05889cfc527a --- /dev/null +++ b/drivers/power/max17085_battery.c @@ -0,0 +1,399 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/* + * MAX17085 Battery driver + */ + +#include <linux/module.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/power_supply.h> +#include <linux/jiffies.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <mach/gpio.h> + +struct max17085_chip { + struct device *dev; + + /*gpio*/ + int pwr_good; + int ac_in; + int charge_now; + int charge_done; + + struct power_supply ac; + struct power_supply bat; + struct delayed_work work; + + int online; + int health; + int status; + int voltage_uV; + int cap; +}; + +#define MAX17085_DELAY 3000 +#define MAX17085_DEF_TEMP 30 + +static int max17085_bat_get_mfr(struct power_supply *psy, + union power_supply_propval *val) +{ + val->strval = "unknown"; + return 0; +} + +static int max17085_bat_get_tech(struct power_supply *psy, + union power_supply_propval *val) +{ + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + return 0; +} + +static int max17085_bat_get_cap(struct power_supply *psy, + union power_supply_propval *val) +{ + struct max17085_chip *chip = container_of(psy, + struct max17085_chip, bat); + + val->intval = chip->cap; + return 0; +} + +static int max17085_bat_get_volt(struct power_supply *psy, + union power_supply_propval *val) +{ + struct max17085_chip *chip = container_of(psy, + struct max17085_chip, bat); + + val->intval = chip->voltage_uV; + return 0; +} + +static int max17085_bat_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + struct max17085_chip *chip = container_of(psy, + struct max17085_chip, bat); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = chip->status; + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = chip->health; + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = max17085_bat_get_cap(psy, val); + if (ret) + return ret; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = max17085_bat_get_volt(psy, val); + if (ret) + return ret; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + ret = max17085_bat_get_mfr(psy, val); + if (ret) + return ret; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + ret = max17085_bat_get_tech(psy, val); + if (ret) + return ret; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = MAX17085_DEF_TEMP; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int max17085_ac_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max17085_chip *chip = container_of(psy, + struct max17085_chip, ac); + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = chip->online; + break; + default: + break; + } + + return 0; +} + +static void max17085_get_online(struct max17085_chip *chip) +{ + int level = gpio_get_value(chip->ac_in); + int cur_online = !level; + + if (chip->online != cur_online) { + chip->online = cur_online; + power_supply_changed(&chip->ac); + } +} + +static void max17085_get_health(struct max17085_chip *chip) +{ + int level = gpio_get_value(chip->pwr_good); + + if (level && (chip->voltage_uV >= 0)) + chip->health = POWER_SUPPLY_HEALTH_GOOD; + else + chip->health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; +} + +extern int da9052_adc_read(unsigned char channel); +#define VOLT_REG_TO_MV(val) ((val * 2500) / 1024) +#define BATT_TO_ADC_SCALE 11 +#define DA9052_ADCMAN_ADCIN6 6 +static void max17085_get_volt(struct max17085_chip *chip) +{ + int val; + val = da9052_adc_read(DA9052_ADCMAN_ADCIN6); + + /* Ignore lower 2 bits out of 10 bits due to noise */ + val = val & 0x3fc; + if (val > 0) + chip->voltage_uV = VOLT_REG_TO_MV(val)*1000*BATT_TO_ADC_SCALE; + else + chip->voltage_uV = -1; +} + +#define BATT_EMPTY_MV 9955 +#define BATT_FULL_MV 12000 +static void max17085_get_cap(struct max17085_chip *chip) +{ + int old_cap = chip->cap; + + if (chip->voltage_uV > BATT_EMPTY_MV*1000) { + chip->cap = (chip->voltage_uV/1000 - BATT_EMPTY_MV) * 100/ + (BATT_FULL_MV - BATT_EMPTY_MV); + if (chip->cap > 100) + chip->cap = 100; + } else + chip->cap = 0; + + if (chip->cap != old_cap) + power_supply_changed(&chip->bat); +} + +static void max17085_update_status(struct max17085_chip *chip) +{ + int old_status = chip->status; + + if (chip->online) { + if (chip->voltage_uV/1000 < BATT_FULL_MV) + chip->status = + POWER_SUPPLY_STATUS_CHARGING; + else + chip->status = + POWER_SUPPLY_STATUS_NOT_CHARGING; + } else + chip->status = POWER_SUPPLY_STATUS_DISCHARGING; + + if (chip->voltage_uV/1000 >= BATT_FULL_MV) + chip->status = POWER_SUPPLY_STATUS_FULL; + + if (old_status != POWER_SUPPLY_STATUS_UNKNOWN && + old_status != chip->status) + power_supply_changed(&chip->bat); + + if (chip->cap < 20) { + gpio_set_value(chip->charge_now, 1); + gpio_set_value(chip->charge_done, 0); + } else if (chip->cap < 80) { + gpio_set_value(chip->charge_now, 1); + gpio_set_value(chip->charge_done, 1); + } else { + gpio_set_value(chip->charge_now, 0); + gpio_set_value(chip->charge_done, 1); + } +} + +static void max17085_work(struct work_struct *work) +{ + struct max17085_chip *chip = container_of(work, + struct max17085_chip, work.work); + + max17085_get_online(chip); + max17085_get_volt(chip); + max17085_get_health(chip); + max17085_get_cap(chip); + max17085_update_status(chip); + + schedule_delayed_work(&chip->work, msecs_to_jiffies(MAX17085_DELAY)); +} + +static enum power_supply_property max17085_bat_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_MANUFACTURER, +}; + +static enum power_supply_property max17085_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static int max17085_bat_probe(struct platform_device *pdev) +{ + int ret = 0; + struct max17085_chip *chip; + struct resource *res; + + chip = kzalloc(sizeof(struct max17085_chip), GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + goto chip_alloc_failed; + } + + res = platform_get_resource_byname(pdev, + IORESOURCE_IO, "pwr-good"); + if (res == NULL) { + ret = -EINVAL; + goto resource_failed; + } + chip->pwr_good = res->start; + res = platform_get_resource_byname(pdev, + IORESOURCE_IO, "ac-in"); + if (res == NULL) { + ret = -EINVAL; + goto resource_failed; + } + chip->ac_in = res->start; + res = platform_get_resource_byname(pdev, + IORESOURCE_IO, "charge-now"); + if (res == NULL) { + ret = -EINVAL; + goto resource_failed; + } + chip->charge_now = res->start; + res = platform_get_resource_byname(pdev, + IORESOURCE_IO, "charge-done"); + if (res == NULL) { + ret = -EINVAL; + goto resource_failed; + } + chip->charge_done = res->start; + + chip->dev = &pdev->dev; + chip->bat.name = "battery"; + chip->bat.type = POWER_SUPPLY_TYPE_BATTERY; + chip->bat.properties = max17085_bat_props; + chip->bat.num_properties = ARRAY_SIZE(max17085_bat_props); + chip->bat.get_property = max17085_bat_get_property; + chip->bat.use_for_apm = 1; + + chip->ac.name = "ac"; + chip->ac.type = POWER_SUPPLY_TYPE_MAINS; + chip->ac.properties = max17085_ac_props; + chip->ac.num_properties = ARRAY_SIZE(max17085_ac_props); + chip->ac.get_property = max17085_ac_get_property; + + platform_set_drvdata(pdev, chip); + + ret = power_supply_register(&pdev->dev, &chip->ac); + if (ret) { + dev_err(chip->dev, "failed to register ac\n"); + goto register_ac_failed; + } + + ret = power_supply_register(&pdev->dev, &chip->bat); + if (ret) { + dev_err(chip->dev, "failed to register battery\n"); + goto register_batt_failed; + } + + max17085_get_online(chip); + + INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17085_work); + schedule_delayed_work(&chip->work, msecs_to_jiffies(MAX17085_DELAY)); + + return ret; + +register_batt_failed: + power_supply_unregister(&chip->ac); +register_ac_failed: +resource_failed: + kfree(chip); +chip_alloc_failed: + return ret; +} + +static int max17085_bat_remove(struct platform_device *pdev) +{ + struct max17085_chip *chip = platform_get_drvdata(pdev); + + cancel_delayed_work(&chip->work); + power_supply_unregister(&chip->bat); + power_supply_unregister(&chip->ac); + kfree(chip); + + return 0; +} + +static void max17085_bat_shutdown(struct platform_device *pdev) +{ + struct max17085_chip *chip = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&chip->work); + gpio_set_value(chip->charge_now, 0); + gpio_set_value(chip->charge_done, 0); +} + +static struct platform_driver max17085_bat_driver = { + .probe = max17085_bat_probe, + .remove = max17085_bat_remove, + .shutdown = max17085_bat_shutdown, + .driver = { + .name = "max17085_bat", + }, + +}; + +static int __devinit max17085_bat_init(void) +{ + return platform_driver_register(&max17085_bat_driver); +} + +static void __devexit max17085_bat_exit(void) +{ + platform_driver_unregister(&max17085_bat_driver); +} + +module_init(max17085_bat_init); +module_exit(max17085_bat_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MAX17085 battery driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 09882ddd8d92..0ec4666f977d 100755 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -142,12 +142,12 @@ struct regulator_info da9052_regulators[] = { DA9052_BUCK_MEM_VOLT_LOWER, DA9052_BUCK_MEM_STEP, DA9052_BUCKMEM_REG, DA9052_BUCKMEM_VBMEM, DA9052_BUCKMEM_BMEMEN), -#if defined (CONFIG_PMIC_DA9052) +#if defined(CONFIG_PMIC_DA9052) DA9052_LDO(DA9052_BUCK_PERI, DA9052_BUCK_PERI_VOLT_UPPER, DA9052_BUCK_PERI_VOLT_LOWER, DA9052_BUCK_PERI_STEP_BELOW_3000, DA9052_BUCKPERI_REG, DA9052_BUCKPERI_VBPERI, DA9052_BUCKPERI_BPERIEN), -#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx) +#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx) DA9052_LDO(DA9052_BUCK_PERI, DA9052_BUCK_PERI_VOLT_UPPER, DA9052_BUCK_PERI_VOLT_LOWER, DA9052_BUCK_PERI_STEP, DA9052_BUCKPERI_REG, @@ -247,7 +247,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev, int id = rdev_get_id(rdev); int ret; int ldo_volt = 0; - selector; + (void)selector; /* Below if condition is there for added setvoltage attribute in sysfs */ @@ -265,7 +265,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev, if (max_uV < da9052_regulators[id].reg_const.min_uV || max_uV > da9052_regulators[id].reg_const.max_uV) return -EINVAL; -#if defined (CONFIG_PMIC_DA9052) +#if defined(CONFIG_PMIC_DA9052) /* Get the ldo register value */ /* Varying step size for BUCK PERI */ if ((da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) && @@ -283,7 +283,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev, da9052_regulators[id].reg_const.min_uV > max_uV) return -EINVAL; } -#elif defined (CONFIG_PMIC_DA9053AA) ||(CONFIG_PMIC_DA9053Bx) +#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx) ldo_volt = (min_uV - da9052_regulators[id].reg_const.min_uV)/ (da9052_regulators[id].step_uV); /* Check for maximum value */ @@ -378,7 +378,7 @@ int da9052_ldo_buck_get_voltage(struct regulator_dev *rdev) da9052_unlock(priv->da9052); ldo_volt = ssc_msg.data & da9052_regulators[id].mask_bits; -#if defined (CONFIG_PMIC_DA9052) +#if defined(CONFIG_PMIC_DA9052) if (da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) { if (ldo_volt >= DA9052_BUCK_PERI_VALUES_UPTO_3000) { ldo_volt_uV = ((DA9052_BUCK_PERI_VALUES_UPTO_3000 * @@ -396,7 +396,7 @@ int da9052_ldo_buck_get_voltage(struct regulator_dev *rdev) ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV; } -#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx) +#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx) ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV; #endif diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 04ce02869d9c..d052adff55c4 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -431,8 +431,7 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); - int hi, value, mask, id = rdev_get_id(rdev); - u32 valread; + int hi, value, val, mask, id = rdev_get_id(rdev); int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", @@ -448,7 +447,7 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, - mc13892_regulators[id].vsel_reg, &valread); + mc13892_regulators[id].vsel_reg, &val); if (ret) goto err; @@ -465,10 +464,8 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, value = (value - 600000) / 25000; mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; - valread = (valread & ~mask) | - (value << mc13892_regulators[id].vsel_shift); - ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg, - valread); + ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, + mask, value << mc13892_regulators[id].vsel_shift); err: mc13xxx_unlock(priv->mc13xxx); diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 952a106ebb19..dd6bf53457b2 100755 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2009 Dialog Semiconductor Ltd. + * Copyright 2010-2012 Freescale Semiconductor, 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 @@ -50,13 +51,12 @@ void da9052_rtc_notifier(struct da9052_eh_nb *eh_data, unsigned int event) da9052_unlock(rtc->da9052); - if (msg.data & DA9052_ALARMMI_ALARMTYPE) { da9052_rtc_enable_alarm(rtc->da9052, 0); - printk(KERN_INFO "RTC: TIMER ALARM\n"); + pr_debug("RTC: TIMER ALARM\n"); } else { kobject_uevent(&rtc->rtc->dev.kobj, KOBJ_CHANGE); - printk(KERN_INFO "RTC: TICK ALARM\n"); + pr_debug("RTC: TICK ALARM\n"); } } @@ -261,8 +261,6 @@ static int da9052_alarm_settime(struct da9052 *da9052, struct rtc_time *rtc_tm) unsigned char loop_index = 0; int ret = 0; - rtc_tm->tm_sec = 0; - /* System compatability */ rtc_tm->tm_year -= 100; rtc_tm->tm_mon += 1; @@ -281,6 +279,24 @@ static int da9052_alarm_settime(struct da9052 *da9052, struct rtc_time *rtc_tm) return ret; } + /* Since DA9053 does support seconds timer, go to next mins boundary */ + if (rtc_tm->tm_sec) { + rtc_tm->tm_min = rtc_tm->tm_min + 1; + rtc_tm->tm_sec = 0; + + /* If minutes rolls over the boundary */ + if (rtc_tm->tm_min > 59) { + rtc_tm->tm_hour = rtc_tm->tm_hour + 1; + rtc_tm->tm_min = 0; + + /* If hours rolls over the boundary */ + if (rtc_tm->tm_hour > 23) { + rtc_tm->tm_mday = rtc_tm->tm_mday + 1; + rtc_tm->tm_hour = 0; + } + } + } + msg.data = msg.data & ~(DA9052_ALARMMI_ALARMMIN); msg.data |= rtc_tm->tm_min; @@ -309,9 +325,8 @@ static int da9052_alarm_settime(struct da9052 *da9052, struct rtc_time *rtc_tm) } msg.data = msg.data & ~(DA9052_ALARMY_ALARMYEAR); - - msg.data |= rtc_tm->tm_year; + msg_arr[loop_index].addr = DA9052_ALARMY_REG; msg_arr[loop_index].data = 0; msg_arr[loop_index++].data = msg.data; @@ -336,8 +351,8 @@ static int da9052_rtc_get_alarm_status(struct da9052 *da9052) da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret != 0) { - da9052_unlock(da9052); - return ret; + da9052_unlock(da9052); + return ret; } da9052_unlock(da9052); @@ -370,45 +385,14 @@ static int da9052_rtc_enable_alarm(struct da9052 *da9052, unsigned char flag) da9052_unlock(da9052); return ret; } - da9052_unlock(da9052); - - return 0; -} - - -static ssize_t da9052_rtc_mask_irq(struct da9052 *da9052) - { - unsigned char data = 0; - ssize_t ret = 0; - struct da9052_ssc_msg ssc_msg; - - ssc_msg.addr = DA9052_IRQMASKA_REG; - ssc_msg.data = 0; - - da9052_lock(da9052); - ret = da9052->read(da9052, &ssc_msg); - if (ret != 0) { - da9052_unlock(da9052); - return ret; - } - - data = ret; - ssc_msg.data = data |= DA9052_IRQMASKA_MALRAM; - - ret = da9052->write(da9052, &ssc_msg); - if (ret != 0) { - da9052_unlock(da9052); - return ret; - } da9052_unlock(da9052); + return 0; } - static ssize_t da9052_rtc_unmask_irq(struct da9052 *da9052) { - unsigned char data = 0; ssize_t ret = 0; struct da9052_ssc_msg ssc_msg; @@ -422,8 +406,8 @@ static ssize_t da9052_rtc_unmask_irq(struct da9052 *da9052) return ret; } - data = ret; - ssc_msg.data = data &= ~DA9052_IRQMASKA_MALRAM; + ssc_msg.data &= ~DA9052_IRQMASKA_MALRAM; + ssc_msg.data |= DA9052_IRQMASKA_MSEQRDY; ret = da9052->write(da9052, &ssc_msg); if (ret != 0) { @@ -462,6 +446,7 @@ static int da9052_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) int ret; struct rtc_time *tm = &alrm->time; struct da9052 *da9052 = dev_get_drvdata(dev->parent); + ret = da9052_alarm_gettime(da9052, tm); if (ret) @@ -479,29 +464,19 @@ static int da9052_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; struct da9052 *da9052 = dev_get_drvdata(dev->parent); - ret = da9052_alarm_settime(da9052, tm); + ret = da9052_rtc_enable_alarm(da9052, 0); + if (ret) + return ret; + ret = da9052_alarm_settime(da9052, tm); if (ret) return ret; ret = da9052_rtc_enable_alarm(da9052, 1); + if (ret) + return ret; - return ret; -} - -static int da9052_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct da9052_rtc *priv = dev_get_drvdata(dev); - int ret = -ENODATA; - - da9052_lock(priv->da9052); - - ret = (enabled ? da9052_rtc_unmask_irq : da9052_rtc_mask_irq) - (priv->da9052); - - da9052_unlock(priv->da9052); - + ret = da9052_rtc_unmask_irq(da9052); return ret; } @@ -510,10 +485,7 @@ static int da9052_rtc_alarm_irq_enable(struct device *dev, { struct da9052_rtc *priv = dev_get_drvdata(dev); - if (enabled) - return da9052_rtc_enable_alarm(priv->da9052, enabled); - else - return da9052_rtc_enable_alarm(priv->da9052, enabled); + return da9052_rtc_enable_alarm(priv->da9052, enabled); } static const struct rtc_class_ops da9052_rtc_ops = { @@ -521,10 +493,7 @@ static const struct rtc_class_ops da9052_rtc_ops = { .set_time = da9052_rtc_class_ops_settime, .read_alarm = da9052_rtc_readalarm, .set_alarm = da9052_rtc_setalarm, -#if 0 - .update_irq_enable = da9052_rtc_update_irq_enable, .alarm_irq_enable = da9052_rtc_alarm_irq_enable, -#endif }; @@ -553,7 +522,7 @@ static int __devinit da9052_rtc_probe(struct platform_device *pdev) goto err_register_alarm; priv->is_min_alarm = 1; - priv->enable_tick_alarm = 1; + priv->enable_tick_alarm = 0; priv->enable_clk_buffer = 1; priv->set_osc_trim_freq = 5; /* Enable/Disable TICK Alarm */ @@ -635,6 +604,8 @@ static int __devinit da9052_rtc_probe(struct platform_device *pdev) goto err_ssc_comm; } da9052_unlock(priv->da9052); + /* disable rtc-alarm */ + da9052_rtc_enable_alarm(priv->da9052, 0); priv->rtc = rtc_device_register(pdev->name, &pdev->dev, &da9052_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-mc34708.c b/drivers/rtc/rtc-mc34708.c index 31e58f9e9cff..95bdc7834a23 100644 --- a/drivers/rtc/rtc-mc34708.c +++ b/drivers/rtc/rtc-mc34708.c @@ -2,7 +2,7 @@ /* * RTC Driver for Freescale MC34708 PMIC * - * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2012 Freescale Semiconductor, Inc. * * Based on mc13xxx rtc driver : * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> @@ -306,12 +306,6 @@ static irqreturn_t mc34708_rtc_update_handler(int irq, void *dev) } static int -mc34708_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - return mc34708_rtc_irq_enable(dev, enabled, MC_PMIC_IRQ_1HZ); -} - -static int mc34708_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { return mc34708_rtc_irq_enable(dev, enabled, MC_PMIC_IRQ_TODA); @@ -323,7 +317,6 @@ static const struct rtc_class_ops mc34708_rtc_ops = { .read_alarm = mc34708_rtc_read_alarm, .set_alarm = mc34708_rtc_set_alarm, .alarm_irq_enable = mc34708_rtc_alarm_irq_enable, - .update_irq_enable = mc34708_rtc_update_irq_enable, }; static irqreturn_t mc34708_rtc_reset_handler(int irq, void *dev) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 80e8c78907e2..4cb728e63abe 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -192,6 +192,15 @@ static int pwm_backlight_resume(struct platform_device *pdev) #define pwm_backlight_resume NULL #endif +void pwm_backlight_shutdown(struct platform_device *pdev) +{ + struct backlight_device *bl = platform_get_drvdata(pdev); + struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); + + pwm_config(pb->pwm, 0, pb->period); + pwm_disable(pb->pwm); +} + static struct platform_driver pwm_backlight_driver = { .driver = { .name = "pwm-backlight", @@ -201,6 +210,7 @@ static struct platform_driver pwm_backlight_driver = { .remove = pwm_backlight_remove, .suspend = pwm_backlight_suspend, .resume = pwm_backlight_resume, + .shutdown = pwm_backlight_shutdown, }; static int __init pwm_backlight_init(void) diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index a41001c834c6..2879040d745e 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -111,6 +111,8 @@ struct mxcfb_info { #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend fbdrv_earlysuspend; #endif + int panel_width_mm; + int panel_height_mm; }; struct mxcfb_pfmt { @@ -895,8 +897,16 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->pixclock); } - var->height = -1; - var->width = -1; + if (mxc_fbi->panel_height_mm) + var->height = mxc_fbi->panel_height_mm; + else + var->height = -1; + + if (mxc_fbi->panel_width_mm) + var->width = mxc_fbi->panel_width_mm; + else + var->width = -1; + var->grayscale = 0; return 0; @@ -2367,6 +2377,9 @@ static int mxcfb_probe(struct platform_device *pdev) mxcfbi->ipu_int_clk = plat_data->int_clk; mxcfbi->late_init = plat_data->late_init; mxcfbi->first_set_par = true; + mxcfbi->panel_width_mm = plat_data->panel_width_mm; + mxcfbi->panel_height_mm = plat_data->panel_height_mm; + ret = mxcfb_dispdrv_init(pdev, fbi); if (ret < 0) goto init_dispdrv_failed; diff --git a/firmware/imx/sdma/sdma-imx53-to1.bin.ihex b/firmware/imx/sdma/sdma-imx53-to1.bin.ihex index 4b3c996dbcd7..c29ef927877e 100644 --- a/firmware/imx/sdma/sdma-imx53-to1.bin.ihex +++ b/firmware/imx/sdma/sdma-imx53-to1.bin.ihex @@ -1,89 +1,90 @@ -:1000000053444D4101000000000000001C000000AE -:1000100023000000A8000000D604000082020000B7 +:1000000053444D4101000000010000001C000000AD +:1000100025000000B0000000D604000082020000AD :10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC :10003000FFFFFFFFFFFFFFFFA9040000FFFFFFFF1F -:10004000F6FAFFFFFFFFFFFF31030000FFFFFFFF96 +:100040000A050000FFFFFFFF31030000FFFFFFFF75 :10005000EB020000BB180000FFFFFFFF08040000D8 :10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9 :10007000FFFFFFFFAB020000FFFFFFFF7B0300005D :10008000FFFFFFFFFFFFFFFF4C0400006E040000B6 :10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 -:1000A0000000000000180000E3C1DB57E35FE357E6 -:1000B000F352016A8F00D500017D8D00A005EB5D34 -:1000C0007804037D79042C7D367C79041F7CEE5600 -:1000D000000F6006057D0965437E0A62417E209817 -:1000E0000A623E7E09653C7E12051205AD0260077C -:1000F000037DFB55D36D2B98FB55041DD36DC86A4A -:100100002F7F011F03200048E47C5398FB55D76DD7 -:10011000150005780962C86A0962C86AD76D5298E5 -:10012000FB55D76D1500150005780A62C86A0A628A -:10013000C86AD76D5298FB55D76D1500150015008C -:1001400005780B62C86A0B62C86AD76D097CDF6DDF -:10015000077F0000EB55004D077DFAC1E357069875 -:100160000700CC680C6813C20AC20398D9C1E3C166 -:10017000DB57E35FE357F352216A8F00D500017D1F -:100180008D00A005EB5DFB567804037D79042A7D84 -:10019000317C7904207C700B1103EB53000F60035A -:1001A000057D0965377E0A62357E86980A62327E51 -:1001B0000965307E12051205AD026007027C065A01 -:1001C0008E98265A277F011F03200048E87C700B79 -:1001D00011031353AF98150004780962065A096297 -:1001E000265AAE981500150004780A62065A0A626B -:1001F000265AAE9815001500150004780B62065AB1 -:100200000B62265A077C0000EB55004D067DFAC1B3 -:10021000E357699807000C6813C20AC26698700B0E -:10022000110313536C07017CD9C1FB5E8A066B076F -:10023000017CD9C1F35EDB59D3588F0110010F390E -:100240008B003CC12B7DC05AC85B4EC1277C880304 -:100250008906E35CFF0D1105FF1DBC053E07004D3F -:10026000187D700811007E07097D7D07027D2852E8 -:10027000E698F852DB54BC02CC02097C7C07027D74 -:100280002852EF98F852D354BC02CC02097D0004E6 -:10029000DD988B00C052C85359C1D67D0002CD985D -:1002A000FF08BF007F07157D8804D500017D8D0004 -:1002B000A005EB5D8F0212021202FF3ADA05027C02 -:1002C0003E071899A402DD02027D3E0718995E07D9 -:1002D0001899EB559805EB5DF352FB546A07267DA0 -:1002E0006C07017D55996B07577C6907047D68078A -:1002F000027D010E2F999358D600017D8E009355F3 -:10030000A005935DA00602780255045D1D7C004E99 -:10031000087C6907037D0255177E3C99045D147FB4 -:10032000890693500048017D2799A0991500067809 -:100330000255045D4F070255245D2F07017CA099EB -:1003400017006F07017C012093559D000700A7D976 -:10035000F598D36C6907047D6807027D010E6499E6 -:100360009358D600017D8E009355A005935DA0069D -:1003700002780255C86D0F7C004E087C6907037D2A -:100380000255097E7199C86D067F89069350004811 -:10039000017D5C99A0999A99C36A6907047D6807F1 -:1003A000027D010E87999358D600017D8E009355EA -:1003B000A005935DA0060278C865045D0F7C004E21 -:1003C000087C6907037DC865097E9499045D067FF2 -:1003D000890693500048017D7F99A09993559D000F -:1003E0000700FF6CA7D9F5980000E354EB55004DCA -:1003F000017CF598DD98E354EB55FF0A1102FF1AD2 -:100400007F07027CA005B4999D008C05BA05A00564 -:100410001002BA04AD0454040600E3C1DB57FB52DA -:10042000C36AF352056A8F00D500017D8D00A005D7 -:10043000EB5D7804037D79042B7D1E7C7904337C8D -:10044000EE56000FFB556007027DC36DD599041D64 -:10045000C36DC8623C7E6006027D10021202096A0A -:10046000367F1202096A337F1202096A307F011F48 -:1004700003200048E77C099AFB55C76D150015005D -:1004800015000578C8620B6AC8620B6AC76D089AC6 -:10049000FB55C76D150015000578C8620A6AC86269 -:1004A0000A6AC76D089AFB55C76D15000578C862C2 -:1004B000096AC862096AC76D0A7C286ADB57077F28 -:1004C0000000EB55004D057DFAC1DB57BF9977C29F -:1004D00054040AC2BA99D9C1E3C1DB57F352056A81 -:1004E0008F00D500017D8D00A005FB567804037DAB -:1004F0007904297D1F7C79042E7CE35D700D110544 -:10050000ED55000F6007027D0652339A2652337E66 -:100510006005027D10021202096A2D7F1202096A2B -:100520002A7F1202096A277F011F03200048EA7C04 -:10053000E3555E9A150015001500047806520B6A03 -:1005400026520B6A5D9A15001500047806520A6A55 -:1005500026520A6A5D9A150004780652096A2652E4 -:10056000096A097C286A077F0000DB57004D057D7A -:0E057000FAC1DB571C9A77C254040AC2199ACA +:1000A000000000000018000062180000171A00008D +:1000B000E3C1DB57E35FE357F352016A8F00D500DA +:1000C000017D8D00A005EB5D7804037D79042C7D16 +:1000D000367C79041F7CEE56000F6006057D0965AD +:1000E000437E0A62417E20980A623E7E09653C7E1C +:1000F00012051205AD026007037DFB55D36D2B98E9 +:10010000FB55041DD36DC86A2F7F011F03200048D3 +:10011000E47C5398FB55D76D150005780962C86AD1 +:100120000962C86AD76D5298FB55D76D1500150046 +:1001300005780A62C86A0A62C86AD76D5298FB5588 +:10014000D76D15001500150005780B62C86A0B62A3 +:10015000C86AD76D097CDF6D077F0000EB55004D45 +:10016000077DFAC1E35706980700CC680C6813C2F4 +:100170000AC20398D9C1E3C1DB57E35FE357F352E7 +:10018000216A8F00D500017D8D00A005EB5DFB5637 +:100190007804037D79042A7D317C7904207C700BFE +:1001A0001103EB53000F6003057D0965377E0A627A +:1001B000357E86980A62327E0965307E1205120508 +:1001C000AD026007027C065A8E98265A277F011FCF +:1001D00003200048E87C700B11031353AF981500FF +:1001E00004780962065A0962265AAE98150015006D +:1001F00004780A62065A0A62265AAE98150015005B +:10020000150004780B62065A0B62265A077C000020 +:10021000EB55004D067DFAC1E357699807000C685D +:1002200013C20AC26698700B110313536C07017C4A +:10023000D9C1FB5E8A066B07017CD9C1F35EDB592D +:10024000D3588F0110010F398B003CC12B7DC05A50 +:10025000C85B4EC1277C88038906E35CFF0D11054E +:10026000FF1DBC053E07004D187D700811007E077C +:10027000097D7D07027D2852E698F852DB54BC02C6 +:10028000CC02097C7C07027D2852EF98F852D354A7 +:10029000BC02CC02097D0004DD988B00C052C8531B +:1002A00059C1D67D0002CD98FF08BF007F07157D9C +:1002B0008804D500017D8D00A005EB5D8F02120240 +:1002C0001202FF3ADA05027C3E071899A402DD0209 +:1002D000027D3E0718995E071899EB559805EB5D6E +:1002E000F352FB546A07267D6C07017D55996B0715 +:1002F000577C6907047D6807027D010E2F9993588A +:10030000D600017D8E009355A005935DA00602786E +:100310000255045D1D7C004E087C6907037D025573 +:10032000177E3C99045D147F890693500048017D37 +:100330002799A099150006780255045D4F070255CC +:10034000245D2F07017CA09917006F07017C012015 +:1003500093559D000700A7D9F598D36C6907047DD4 +:100360006807027D010E64999358D600017D8E00C6 +:100370009355A005935DA00602780255C86D0F7CC9 +:10038000004E087C6907037D0255097E7199C86D8E +:10039000067F890693500048017D5C99A0999A993F +:1003A000C36A6907047D6807027D010E8799935827 +:1003B000D600017D8E009355A005935DA0060278BE +:1003C000C865045D0F7C004E087C6907037DC86525 +:1003D000097E9499045D067F890693500048017D4B +:1003E0007F99A09993559D000700FF6CA7D9F598B8 +:1003F0000000E354EB55004D017CF598DD98E35483 +:10040000EB55FF0A1102FF1A7F07027CA005B49981 +:100410009D008C05BA05A0051002BA04AD04540471 +:100420000600E3C1DB57FB52C36AF352056A8F0033 +:10043000D500017D8D00A005EB5D7804037D790476 +:100440002B7D1E7C7904337CEE56000FFB55600734 +:10045000027DC36DD599041DC36DC8623C7E6006E4 +:10046000027D10021202096A367F1202096A337F86 +:100470001202096A307F011F03200048E77C099AB5 +:10048000FB55C76D1500150015000578C8620B6A8D +:10049000C8620B6AC76D089AFB55C76D1500150039 +:1004A0000578C8620A6AC8620A6AC76D089AFB556D +:1004B000C76D15000578C862096AC862096AC76D08 +:1004C0000A7C286ADB57077F0000EB55004D057D4D +:1004D000FAC1DB57BF9977C254040AC2BA99D9C18D +:1004E000E3C1DB57F352056A8F00D500017D8D0013 +:1004F000A005FB567804037D7904297D1F7C7904CF +:100500002E7CE35D700D1105ED55000F6007027D37 +:100510000652339A2652337E6005027D1002120283 +:10052000096A2D7F1202096A2A7F1202096A277F4F +:10053000011F03200048EA7CE3555E9A1500150070 +:100540001500047806520B6A26520B6A5D9A150054 +:100550001500047806520A6A26520A6A5D9A150046 +:1005600004780652096A2652096A097C286A077FBC +:100570000000DB57004D057DFAC1DB571C9A77C29E +:0605800054040AC2199A9E :00000001FF diff --git a/include/linux/i2c/mpr.h b/include/linux/i2c/mpr.h index ded00db775f3..8dbbee648098 100644 --- a/include/linux/i2c/mpr.h +++ b/include/linux/i2c/mpr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -43,6 +43,7 @@ * should be write at last. */ #define ELECTRODE_CONF_ADDR 0x5e +#define ECR_CL_BT_5BIT_VAL 0x80 #define AUTO_CONFIG_CTRL_ADDR 0x7b /* AUTO_CONFIG_USL: Upper Limit for auto baseline search, this * register is related to VDD supplied on your board, the value of @@ -55,7 +56,7 @@ #define AUTO_CONFIG_TL_ADDR 0x7f /* Threshold of touch/release trigger */ -#define TOUCH_THRESHOLD 0x0f +#define TOUCH_THRESHOLD 0x0c #define RELEASE_THRESHOLD 0x0a /* Mask Button bits of STATUS_0 & STATUS_1 register */ #define TOUCH_STATUS_MASK 0xfff diff --git a/include/linux/mfd/da9052/da9052.h b/include/linux/mfd/da9052/da9052.h index fd83f73bcd82..18dd74bde4f8 100755 --- a/include/linux/mfd/da9052/da9052.h +++ b/include/linux/mfd/da9052/da9052.h @@ -75,6 +75,9 @@ #define DA9052_SSC_I2C_REPEAT_WRITE_MODE 1 #define DA9052_SSC_I2C_WRITE_MODE DA9052_SSC_I2C_REPEAT_WRITE_MODE +#define DA9053_VERSION_AA 1 +#define DA9053_VERSION_BB 2 + struct da9052_ssc_msg { unsigned char data; unsigned char addr; @@ -95,7 +98,6 @@ struct da9052_eh_nb{ struct da9052_regulator_init_data { struct regulator_init_data *init_data; int id; - }; struct da9052_regulator_platform_data { @@ -114,6 +116,25 @@ struct da9052_tsi_platform_data { }; +struct da9052_bat_platform_data { + u16 sw_temp_control_en; + u16 monitoring_interval; + u16 sw_bat_temp_threshold; + u16 sw_junc_temp_threshold; + u16 hysteresis_window_size; + u16 current_monitoring_window; + u16 bat_with_no_resistor; + u16 bat_capacity_limit_low; + u16 bat_capacity_full; + u16 bat_capacity_limit_high; + u16 chg_hysteresis_const; + u16 hysteresis_reading_interval; + u16 hysteresis_no_of_reading; + u16 filter_size; + u16 bat_volt_cutoff; + u16 vbat_first_valid_detect_iteration; +}; + struct da9052 { struct mutex ssc_lock; struct mutex eve_nb_lock; @@ -143,9 +164,9 @@ struct da9052 { struct device *dev; struct i2c_adapter *adapter; unsigned char slave_addr; + int chip_version; }; - struct da9052_platform_data { int (*init)(struct da9052 *da9052); int irq_high; @@ -156,6 +177,7 @@ struct da9052_platform_data { struct regulator_init_data *regulators; struct da9052_leds_platform_data *led_data; struct da9052_tsi_platform_data *tsi_data; + struct da9052_bat_platform_data *bat_data; }; struct da9052_ssc_ops { @@ -206,4 +228,6 @@ int eh_register_nb(struct da9052 *da9052, struct da9052_eh_nb *nb); int eh_unregister_nb(struct da9052 *da9052, struct da9052_eh_nb *nb); int da9052_manual_read(struct da9052 *da9052, unsigned char channel); +void da9053_power_off(void); +int da9053_get_chip_version(void); #endif /* __LINUX_MFD_DA9052_DA9052_H */ diff --git a/include/linux/mfd/da9052/pm.h b/include/linux/mfd/da9052/pm.h index 9a1c4f8b4ea8..f5901e8f1ed1 100644 --- a/include/linux/mfd/da9052/pm.h +++ b/include/linux/mfd/da9052/pm.h @@ -50,14 +50,14 @@ #define DA9052_BUCK_MEM_VOLT_UPPER 2500 #define DA9052_BUCK_MEM_VOLT_LOWER 925 #define DA9052_BUCK_MEM_STEP 25 -#if defined (CONFIG_PMIC_DA9052) +#if defined(CONFIG_PMIC_DA9052) #define DA9052_BUCK_PERI_VOLT_UPPER 3600 #define DA9052_BUCK_PERI_VOLT_LOWER 1800 #define DA9052_BUCK_PERI_STEP_BELOW_3000 50 #define DA9052_BUCK_PERI_STEP_ABOVE_3000 100000 #define DA9052_BUCK_PERI_VALUES_UPTO_3000 24 #define DA9052_BUCK_PERI_VALUES_3000 3000000 -#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx) +#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx) #define DA9052_BUCK_PERI_VOLT_UPPER 2500 #define DA9052_BUCK_PERI_VOLT_LOWER 925 #define DA9052_BUCK_PERI_STEP 25 diff --git a/include/linux/mfd/da9052/reg.h b/include/linux/mfd/da9052/reg.h index 9daaa02e565f..8c4c9dff8fe5 100644 --- a/include/linux/mfd/da9052/reg.h +++ b/include/linux/mfd/da9052/reg.h @@ -533,10 +533,10 @@ /* BUCKPERI REGISTER */ #define DA9052_BUCKPERI_BPERICONF (1<<7) #define DA9052_BUCKPERI_BPERIEN (1<<6) -#if defined (CONFIG_PMIC_DA9052) +#if defined(CONFIG_PMIC_DA9052) #define DA9052_BUCKPERI_BPERIHS (1<<5) #define DA9052_BUCKPERI_VBPERI (31<<0) -#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx) +#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx) #define DA9052_BUCKPERI_VBPERI (63<<0) #endif @@ -663,7 +663,7 @@ #define DA9052_BOOST_BOOSTEN (1<<0) /* LED COUNT REGISTER */ -#if defined (CONFIG_PMIC_DA9053Bx) +#if defined(CONFIG_PMIC_DA9053Bx) #define DA9052_LEDCONT_SELLEDMODE (1<<7) #endif #define DA9052_LEDCONT_LED3ICONT (1<<6) diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index 72d85503d495..7fb135ab70f1 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -52,7 +52,7 @@ config SND_SOC_PHYCORE_AC97 config SND_SOC_IMX_SGTL5000 tristate "SoC Audio support for i.MX boards with sgtl5000" - depends on I2C && (MACH_MX35_3DS || MACH_MX51_BABBAGE \ + depends on I2C && (MACH_MX35_3DS || MACH_MX51_BABBAGE || MACH_MX53_SMD \ || MACH_MX6Q_SABRELITE || MACH_MX6Q_ARM2) select SND_SOC_SGTL5000 select SND_MXC_SOC_MX2 diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index 342f9c85f481..a7f9e12af734 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -577,6 +577,7 @@ static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream, } } +#ifdef CONFIG_ARCH_MX6 static void hdmi_sdma_isr(void *data) { struct imx_hdmi_dma_runtime_data *rtd = data; @@ -637,7 +638,7 @@ static void hdmi_sdma_isr(void *data) return; } - +#endif static irqreturn_t hdmi_dma_isr(int irq, void *dev_id) { @@ -925,6 +926,7 @@ static int hdmi_dma_copy(struct snd_pcm_substream *substream, int channel, return 0; } +#ifdef CONFIG_ARCH_MX6 static bool hdmi_filter(struct dma_chan *chan, void *param) { @@ -1020,8 +1022,7 @@ static int hdmi_sdma_config(struct imx_hdmi_dma_runtime_data *params) return 0; } - - +#endif static int hdmi_dma_hw_free(struct snd_pcm_substream *substream) { @@ -1039,7 +1040,9 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_hdmi_dma_runtime_data *rtd = runtime->private_data; +#ifdef CONFIG_ARCH_MX6 int err; +#endif rtd->buffer_bytes = params_buffer_bytes(params); rtd->periods = params_periods(params); @@ -1070,6 +1073,7 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream, } rtd->dma_period_bytes = rtd->period_bytes * rtd->buffer_ratio; +#ifdef CONFIG_ARCH_MX6 if (hdmi_SDMA_check()) { rtd->sdma_params.buffer_num = rtd->periods; rtd->sdma_params.phyaddr = rtd->phy_hdmi_sdma_t; @@ -1087,6 +1091,7 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream, if (err) return err; } +#endif snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); diff --git a/sound/soc/imx/imx-sgtl5000.c b/sound/soc/imx/imx-sgtl5000.c index 9325dc8e346c..c73ab7ec19a4 100644 --- a/sound/soc/imx/imx-sgtl5000.c +++ b/sound/soc/imx/imx-sgtl5000.c @@ -3,7 +3,7 @@ * sgtl5000 codec * * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2012 Freescale Semiconductor, 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 @@ -43,6 +43,11 @@ static struct snd_soc_jack_pin hs_jack_pins[] = { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE, }, + { + .pin = "Ext Spk", + .mask = SND_JACK_HEADPHONE, + .invert = 1, + }, }; /* Headphones jack detection gpios */ @@ -195,11 +200,29 @@ static int sgtl5000_set_line_in(struct snd_kcontrol *kcontrol, return 1; } +static int spk_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct imx_sgtl5000_priv *priv = &card_priv; + struct platform_device *pdev = priv->pdev; + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + + if (plat->amp_enable == NULL) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) + plat->amp_enable(1); + else + plat->amp_enable(0); + + return 0; +} + /* imx_3stack card dapm widgets */ static const struct snd_soc_dapm_widget imx_3stack_dapm_widgets[] = { SND_SOC_DAPM_MIC("Mic Jack", NULL), SND_SOC_DAPM_LINE("Line In Jack", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SPK("Ext Spk", spk_amp_event), SND_SOC_DAPM_HP("Headphone Jack", NULL), }; @@ -246,7 +269,8 @@ static int imx_3stack_sgtl5000_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_disable_pin(&codec->dapm, "Line In Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); snd_soc_dapm_sync(&codec->dapm); if (hs_jack_gpios[0].gpio != -1) { |