summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-06-21 15:03:05 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-06-21 15:03:05 +0800
commitd1276730560909329571ce75427e1c1dac43c9a0 (patch)
treedf724365ee32f8188f9fcdf1e9254cc90f18372a /drivers
parent19f043c9cee6ed78a051ecb244b3406bd21dd0b0 (diff)
parent4e7e9e5834d6f8d9971bddfc7ddb91116226c39d (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.15' into imx_3.0.15_android
Conflicts: arch/arm/mach-mx6/devices-imx6q.h drivers/power/sabresd_battery.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c89
-rwxr-xr-xdrivers/power/sabresd_battery.c172
2 files changed, 195 insertions, 66 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index b4ec41ad90da..db20cbf2971a 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -156,7 +156,8 @@ struct dma_async_tx_descriptor *imx_asrc_dma_config(
struct asrc_pair_params *params,
struct dma_chan *chan,
u32 dma_addr, dma_addr_t buf_addr,
- u32 buf_len, bool in);
+ u32 buf_len, bool in,
+ enum asrc_word_width word_width);
static int asrc_set_clock_ratio(enum asrc_pair_index index,
int input_sample_rate, int output_sample_rate)
@@ -435,10 +436,9 @@ int asrc_config_pair(struct asrc_config *config)
input_sample_rate);
reg |= tmp << AICPA;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->input_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AICPA;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->input_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AICPA;
else
err = -EFAULT;
@@ -454,10 +454,9 @@ int asrc_config_pair(struct asrc_config *config)
output_sample_rate);
reg |= tmp << AOCPA;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->output_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AOCPA;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->output_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AOCPA;
else
err = -EFAULT;
@@ -479,10 +478,9 @@ int asrc_config_pair(struct asrc_config *config)
input_sample_rate);
reg |= tmp << AICPB;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->input_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AICPB;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->input_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AICPB;
else
err = -EFAULT;
@@ -498,10 +496,9 @@ int asrc_config_pair(struct asrc_config *config)
output_sample_rate);
reg |= tmp << AOCPB;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->output_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AOCPB;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->output_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AOCPB;
else
err = -EFAULT;
@@ -523,10 +520,9 @@ int asrc_config_pair(struct asrc_config *config)
input_sample_rate);
reg |= tmp << AICPC;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->input_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AICPC;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->input_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AICPC;
else
err = -EFAULT;
@@ -542,10 +538,9 @@ int asrc_config_pair(struct asrc_config *config)
output_sample_rate);
reg |= tmp << AOCPC;
} else {
- if (config->word_width == 16 || config->word_width == 8)
+ if (config->output_word_width == ASRC_WIDTH_16_BIT)
reg |= 5 << AOCPC;
- else if (config->word_width == 32
- || config->word_width == 24)
+ else if (config->output_word_width == ASRC_WIDTH_24_BIT)
reg |= 6 << AOCPC;
else
err = -EFAULT;
@@ -588,6 +583,36 @@ int asrc_config_pair(struct asrc_config *config)
}
}
+ /* Config input and output wordwidth */
+ reg = __raw_readl(
+ g_asrc->vaddr + ASRC_ASRMCR1A_REG + (config->pair << 2));
+ /* BIT 11-9 stands for input word width,
+ * BIT 0 stands for output word width */
+ reg &= ~0xE01;
+ switch (config->input_word_width) {
+ case ASRC_WIDTH_16_BIT:
+ reg |= 1 << 9;
+ break;
+ case ASRC_WIDTH_24_BIT:
+ reg |= 0 << 9;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (config->output_word_width) {
+ case ASRC_WIDTH_16_BIT:
+ reg |= 1;
+ break;
+ case ASRC_WIDTH_24_BIT:
+ reg |= 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ __raw_writel(reg,
+ g_asrc->vaddr + ASRC_ASRMCR1A_REG + (config->pair << 2));
+
return err;
}
@@ -924,21 +949,35 @@ struct dma_async_tx_descriptor *imx_asrc_dma_config(
struct asrc_pair_params *params,
struct dma_chan *chan,
u32 dma_addr, dma_addr_t buf_addr,
- u32 buf_len, bool in)
+ u32 buf_len, bool in,
+ enum asrc_word_width word_width)
{
struct dma_slave_config slave_config;
+ enum dma_slave_buswidth buswidth;
int ret;
+ switch (word_width) {
+ case ASRC_WIDTH_16_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case ASRC_WIDTH_24_BIT:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ pr_err("Error word_width\n");
+ return NULL;
+ }
+
if (in) {
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = dma_addr;
- slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ slave_config.dst_addr_width = buswidth;
slave_config.dst_maxburst =
ASRC_INPUTFIFO_THRESHOLD * params->channel_nums;
} else {
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = dma_addr;
- slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ slave_config.src_addr_width = buswidth;
slave_config.src_maxburst =
ASRC_OUTPUTFIFO_THRESHOLD * params->channel_nums;
}
@@ -1055,7 +1094,8 @@ static long asrc_ioctl(struct file *file,
params->input_dma_channel,
asrc_get_per_addr(params->index, 1),
params->input_dma[0].dma_paddr,
- params->input_buffer_size, 1);
+ params->input_buffer_size, 1,
+ config.input_word_width);
if (params->desc_in) {
params->desc_in->callback =
asrc_input_dma_callback;
@@ -1075,7 +1115,8 @@ static long asrc_ioctl(struct file *file,
params->output_dma_channel,
asrc_get_per_addr(params->index, 0),
params->output_dma[0].dma_paddr,
- params->output_buffer_size, 0);
+ params->output_buffer_size, 0,
+ config.output_word_width);
if (params->desc_out) {
params->desc_out->callback =
asrc_output_dma_callback;
diff --git a/drivers/power/sabresd_battery.c b/drivers/power/sabresd_battery.c
index 7ea02fc08613..88fe30791dfb 100755
--- a/drivers/power/sabresd_battery.c
+++ b/drivers/power/sabresd_battery.c
@@ -38,6 +38,7 @@ struct max8903_data {
struct max8903_pdata *pdata;
struct device *dev;
struct power_supply psy;
+ struct power_supply usb;
bool fault;
bool usb_in;
bool ta_in;
@@ -53,7 +54,9 @@ struct max8903_data {
int real_capacity;
int percent;
int old_percent;
+ int usb_charger_online;
struct power_supply bat;
+ struct power_supply detect_usb;
struct mutex work_lock;
};
@@ -64,13 +67,14 @@ typedef struct {
static bool capacity_changed_flag;
static int cpu_type_flag;
+static int offset_discharger;
+static int offset_charger;
static battery_capacity chargingTable[] = {
- {4146, 100},
- {4133, 99},
- {4123, 98},
- {4115, 97},
- {4090, 96},
+ {4105, 99},
+ {4100, 98},
+ {4095, 97},
+ {4085, 96},
{4075, 95},
{4060, 94},
{4045, 93},
@@ -98,7 +102,7 @@ static battery_capacity chargingTable[] = {
{0, 0}
};
static battery_capacity dischargingTable[] = {
- {4110, 100},
+ {4050, 100},
{4020, 99},
{3950, 98},
{3920, 97},
@@ -169,24 +173,35 @@ extern u32 max11801_read_adc(void);
static void max8903_charger_update_status(struct max8903_data *data)
{
- if (data->usb_in || data->ta_in)
+ if (data->usb_in || data->ta_in) {
+ if (data->ta_in)
data->charger_online = 1;
- else
- data->charger_online = 0;
- if (data->charger_online == 0) {
+
+ if (data->usb_in)
+ data->usb_charger_online = 1;
+ } else {
+ data->charger_online = 0;
+ data->usb_charger_online = 0;
+ }
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
data->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
} else {
- if (data->pdata->chg) {
if (gpio_get_value(data->pdata->chg) == 0) {
data->battery_status = POWER_SUPPLY_STATUS_CHARGING;
- } else if ((data->usb_in || data->ta_in) &&
+ } else if (data->ta_in &&
gpio_get_value(data->pdata->chg) == 1) {
- if (data->percent == 100)
+ if (data->percent >= 99)
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ else if (data->usb_in &&
+ gpio_get_value(data->pdata->chg) == 1) {
+ if (data->percent >= 99)
data->battery_status = POWER_SUPPLY_STATUS_FULL;
else
data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
}
- }
}
pr_debug("chg: %d \n", gpio_get_value(data->pdata->chg));
}
@@ -207,19 +222,19 @@ u32 calibration_voltage(struct max8903_data *data)
int i;
for (i = 0; i < ADC_SAMPLE_COUNT; i++) {
if (cpu_type_flag == 1) {
- if (data->charger_online == 0) {
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
/* ADC offset when battery is discharger*/
- volt[i] = max11801_read_adc()-1694;
+ volt[i] = max11801_read_adc()-offset_discharger;
} else {
- volt[i] = max11801_read_adc()-1900;
+ volt[i] = max11801_read_adc()-offset_charger;
}
}
if (cpu_type_flag == 0) {
- if (data->charger_online == 0) {
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
/* ADC offset when battery is discharger*/
- volt[i] = max11801_read_adc()-1464;
+ volt[i] = max11801_read_adc()-offset_discharger;
} else {
- volt[i] = max11801_read_adc()-1485;
+ volt[i] = max11801_read_adc()-offset_charger;
}
}
}
@@ -241,7 +256,7 @@ static void max8903_battery_update_status(struct max8903_data *data)
data->old_percent = data->percent;
capacity_changed_flag = true;
}
- if ((capacity_changed_flag == true) && (data->charger_online)) {
+ if ((capacity_changed_flag == true)) {
counter++;
if (counter > 2) {
counter = 0;
@@ -263,19 +278,22 @@ static int max8903_battery_get_property(struct power_supply *bat,
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
- if (di->pdata->chg) {
- if ((di->usb_in || di->ta_in) && gpio_get_value(di->pdata->chg) == 0) {
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- } else if ((di->usb_in || di->ta_in) && gpio_get_value(di->pdata->chg) == 1) {
- if (di->percent == 100)
- di->battery_status = POWER_SUPPLY_STATUS_FULL;
- else
- di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- }
- else {
- di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
- }
- }
+ if (gpio_get_value(di->pdata->chg) == 0) {
+ di->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if (di->ta_in &&
+ gpio_get_value(di->pdata->chg) == 1) {
+ if (di->percent >= 99)
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ else if (di->usb_in &&
+ gpio_get_value(di->pdata->chg) == 1) {
+ if (di->percent >= 99)
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
val->intval = di->battery_status;
return 0;
default:
@@ -323,7 +341,7 @@ static int max8903_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = 0;
- if (data->usb_in || data->ta_in)
+ if (data->ta_in)
val->intval = 1;
data->charger_online = val->intval;
break;
@@ -332,7 +350,25 @@ static int max8903_get_property(struct power_supply *psy,
}
return 0;
}
+static int max8903_get_usb_property(struct power_supply *usb,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8903_data *data = container_of(usb,
+ struct max8903_data, usb);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = 0;
+ if (data->usb_in)
+ val->intval = 1;
+ data->usb_charger_online = val->intval;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
static irqreturn_t max8903_dcin(int irq, void *_data)
{
struct max8903_data *data = _data;
@@ -353,15 +389,12 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
power_supply_changed(&data->bat);
return IRQ_HANDLED;
}
-
static irqreturn_t max8903_usbin(int irq, void *_data)
{
struct max8903_data *data = _data;
struct max8903_pdata *pdata = data->pdata;
bool usb_in;
-
usb_in = gpio_get_value(pdata->uok) ? false : true;
-
if (usb_in == data->usb_in)
return IRQ_HANDLED;
@@ -370,8 +403,8 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
max8903_battery_update_status(data);
pr_info("USB Charger %s.\n", usb_in ?
"Connected" : "Disconnected");
- power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -396,6 +429,7 @@ static irqreturn_t max8903_fault(int irq, void *_data)
max8903_battery_update_status(data);
power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -415,6 +449,7 @@ static irqreturn_t max8903_chg(int irq, void *_data)
max8903_battery_update_status(data);
power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -426,7 +461,6 @@ static void max8903_battery_work(struct work_struct *work)
max8903_charger_update_status(data);
max8903_battery_update_status(data);
-
pr_debug("battery voltage: %4d mV\n" , data->voltage_uV);
pr_debug("charger online status: %d\n" , data->charger_online);
pr_debug("battery status : %d\n" , data->battery_status);
@@ -435,6 +469,40 @@ static void max8903_battery_work(struct work_struct *work)
/* reschedule for the next time */
schedule_delayed_work(&data->work, data->interval);
}
+
+static ssize_t max8903_voltage_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "read offset_discharger:%04d,offset_charger:%04d\n",
+ offset_discharger, offset_charger);
+}
+
+static ssize_t max8903_voltage_offset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ char *p;
+
+ offset_discharger = simple_strtoul(buf, NULL, 10);
+ p = NULL;
+ p = memchr(buf, ' ', count);
+ p += 1;
+ offset_charger = simple_strtoul(p, NULL, 10);
+
+ pr_info("read offset_discharger:%04d,offset_charger:%04d\n",
+ offset_discharger, offset_charger);
+ return count;
+}
+
+static struct device_attribute max8903_dev_attr = {
+ .attr = {
+ .name = "max8903_ctl",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .show = max8903_voltage_offset_show,
+ .store = max8903_voltage_offset_store,
+};
+
static __devinit int max8903_probe(struct platform_device *pdev)
{
struct max8903_data *data;
@@ -457,12 +525,10 @@ static __devinit int max8903_probe(struct platform_device *pdev)
}
data->pdata = pdata;
data->dev = dev;
-
platform_set_drvdata(pdev, data);
capacity_changed_flag = false;
data->usb_in = 0;
data->ta_in = 0;
-
if (pdata->dc_valid == false && pdata->usb_valid == false) {
dev_err(dev, "No valid power sources.\n");
printk(KERN_INFO "No valid power sources.\n");
@@ -562,6 +628,16 @@ static __devinit int max8903_probe(struct platform_device *pdev)
dev_err(dev, "failed: power supply register.\n");
goto err_psy;
}
+ data->usb.name = "max8903-usb";
+ data->usb.type = POWER_SUPPLY_TYPE_USB;
+ data->usb.get_property = max8903_get_usb_property;
+ data->usb.properties = max8903_charger_props;
+ data->usb.num_properties = ARRAY_SIZE(max8903_charger_props);
+ ret = power_supply_register(dev, &data->usb);
+ if (ret) {
+ dev_err(dev, "failed: power supply register.\n");
+ goto err_psy;
+ }
data->bat.name = "max8903-charger";
data->bat.type = POWER_SUPPLY_TYPE_BATTERY;
data->bat.properties = max8903_battery_props;
@@ -623,6 +699,18 @@ static __devinit int max8903_probe(struct platform_device *pdev)
}
}
+ ret = device_create_file(&pdev->dev, &max8903_dev_attr);
+ if (ret)
+ dev_err(&pdev->dev, "create device file failed!\n");
+ if (cpu_type_flag == 1) {
+ offset_discharger = 1694;
+ offset_charger = 1900;
+ }
+ if (cpu_type_flag == 0) {
+ offset_discharger = 1464;
+ offset_charger = 1485;
+ }
+
max8903_charger_update_status(data);
max8903_battery_update_status(data);
return 0;