diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/accessory/30pin_con.c | 148 | ||||
-rw-r--r-- | drivers/accessory/sec_keyboard.c | 46 | ||||
-rw-r--r-- | drivers/accessory/sec_keyboard.h | 5 | ||||
-rw-r--r-- | drivers/irda/ir_remote_con_mc96.c | 189 | ||||
-rw-r--r-- | drivers/misc/sec_jack.c | 2 | ||||
-rw-r--r-- | drivers/power/max17042_fuelgauge_px.c | 49 | ||||
-rw-r--r-- | drivers/power/sec_battery_px.c | 3 | ||||
-rw-r--r-- | drivers/sensor/lsm330dlc_accel.c | 30 | ||||
-rw-r--r-- | drivers/sensor/sensors_core.c | 1 | ||||
-rw-r--r-- | drivers/video/samsung/s3cfb_s6c1372.c | 2 |
10 files changed, 409 insertions, 66 deletions
diff --git a/drivers/accessory/30pin_con.c b/drivers/accessory/30pin_con.c index 3ecaa6205b6..0014afb610d 100644 --- a/drivers/accessory/30pin_con.c +++ b/drivers/accessory/30pin_con.c @@ -67,10 +67,15 @@ struct acc_con_info { struct switch_dev ear_jack_switch; struct wake_lock wake_lock; struct s3c_adc_client *padc; + struct sec_30pin_callbacks callbacks; enum accessory_type current_accessory; + enum accessory_type univ_kdb_accessory; enum dock_type current_dock; int accessory_irq; int dock_irq; + int cable_type; + int cable_sub_type; + int cable_pwr_type; #if defined(CONFIG_MHL_SII9234) || defined(CONFIG_SAMSUNG_MHL_9290) int mhl_irq; bool mhl_pwr_state; @@ -81,7 +86,7 @@ struct acc_con_info { }; #if defined(CONFIG_STMPE811_ADC) -#ifdef CONFIG_MACH_P4NOTE +#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) #define ACCESSORY_ID_ADC_CH 7 #else #define ACCESSORY_ID_ADC_CH 0 @@ -138,6 +143,8 @@ static int acc_get_accessory_id(struct acc_con_info *acc) for (i = 0; i < 5; i++) { adc_val = acc_get_adc_accessroy_id(acc->padc); + ACC_CONDEV_DBG("ACCESSORY_ID adc_val[%d] value = %d", + i, adc_val); adc_buff[i] = adc_val; adc_sum += adc_buff[i]; if (i == 0) { @@ -151,7 +158,8 @@ static int acc_get_accessory_id(struct acc_con_info *acc) } msleep(20); } - adc = (adc_sum - adc_max - adc_min)/3; + /* adc = (adc_sum - adc_max - adc_min)/3; */ + adc = adc_buff[4]; ACC_CONDEV_DBG("ACCESSORY_ID ADC value = %d", adc); return (int)adc; } @@ -323,7 +331,7 @@ static void acc_dock_psy(struct acc_con_info *acc) union power_supply_propval value; /* only support p4note(high current charging) */ -#ifndef CONFIG_MACH_P4NOTE +#if !defined(CONFIG_MACH_P4NOTE) && !defined(CONFIG_MACH_KONA) return; #endif @@ -332,17 +340,65 @@ static void acc_dock_psy(struct acc_con_info *acc) return; } - value.intval = acc->current_dock; + value.intval = 0; + value.intval = (acc->cable_type << 16) + (acc->cable_sub_type << 8) + + (acc->cable_pwr_type << 0); + pr_info("[BATT]30 cx(%d), sub(%d), pwr(%d)\n", + acc->cable_type, acc->cable_sub_type, acc->cable_pwr_type); + psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value); } +void acc_otg_enable_by_univkbd(struct acc_con_info *acc, bool val) +{ + char *env_ptr; + char *stat_ptr; + char *envp[3]; + + if (val == true) { + if (acc->univ_kdb_accessory == ACCESSORY_NONE) { + env_ptr = "ACCESSORY=OTG"; + stat_ptr = "STATE=online"; + acc->univ_kdb_accessory = ACCESSORY_OTG; + + if (acc->pdata->usb_ldo_en) + acc->pdata->usb_ldo_en(1); + if (acc->pdata->otg_en) + acc->pdata->otg_en(1); + + envp[0] = env_ptr; + envp[1] = stat_ptr; + envp[2] = NULL; + kobject_uevent_env(&acc->acc_dev->kobj, + KOBJ_CHANGE, envp); + ACC_CONDEV_DBG("%s : %s", env_ptr, stat_ptr); + } + } else { + if (acc->univ_kdb_accessory == ACCESSORY_OTG) { + env_ptr = "ACCESSORY=OTG"; + stat_ptr = "STATE=offline"; + + envp[0] = env_ptr; + envp[1] = stat_ptr; + envp[2] = NULL; + kobject_uevent_env(&acc->acc_dev->kobj, + KOBJ_CHANGE, envp); + ACC_CONDEV_DBG("%s : %s", env_ptr, stat_ptr); + + if (acc->pdata->otg_en) + acc->pdata->otg_en(0); + + acc->univ_kdb_accessory = ACCESSORY_NONE; + } + } +} + static void acc_check_dock_detection(struct acc_con_info *acc) { if (NULL == acc->pdata->get_dock_state) { ACC_CONDEV_DBG("[30PIN] failed to get acc state!!!"); return; } - if (!acc->pdata->get_dock_state()) { #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard && @@ -355,16 +411,20 @@ static void acc_check_dock_detection(struct acc_con_info *acc) acc->current_dock = DOCK_KEYBOARD; ACC_CONDEV_DBG - ("[30PIN] keyboard dock station attached!!!"); + ("The dock proves to be a keyboard dock..!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_KEYBOARD); + acc->cable_type = POWER_SUPPLY_TYPE_DOCK; + acc->cable_sub_type = ONLINE_SUB_TYPE_DESK; } else #endif { ACC_CONDEV_DBG - ("[30PIN] desktop dock station attached!!!"); + ("The dock proves to be a desktop dock..!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_DESK); acc->current_dock = DOCK_DESK; + acc->cable_type = POWER_SUPPLY_TYPE_DOCK; + acc->cable_sub_type = ONLINE_SUB_TYPE_DESK; #if defined(CONFIG_MHL_SII9234) || defined(CONFIG_SAMSUNG_MHL_9290) mutex_lock(&acc->lock); @@ -382,12 +442,21 @@ static void acc_check_dock_detection(struct acc_con_info *acc) acc_dock_uevent(acc, true); } else { - ACC_CONDEV_DBG("[30PIN] dock station detached!!!"); + ACC_CONDEV_DBG("dock station detached.. !"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_NONE); + acc->current_dock = DOCK_NONE; + acc->cable_type = POWER_SUPPLY_TYPE_BATTERY; + acc->cable_sub_type = ONLINE_SUB_TYPE_UNKNOWN; #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard) acc->pdata->check_keyboard(false); + if (acc->univ_kdb_accessory == ACCESSORY_OTG) { + acc_otg_enable_by_univkbd(acc, false); + acc->current_dock = DOCK_NONE; + acc->cable_type = POWER_SUPPLY_TYPE_BATTERY; + acc->cable_sub_type = ONLINE_SUB_TYPE_UNKNOWN; + } #endif #if defined(CONFIG_MHL_SII9234) || defined(CONFIG_SAMSUNG_MHL_9290) /*call MHL deinit */ @@ -400,11 +469,9 @@ static void acc_check_dock_detection(struct acc_con_info *acc) acc->mhl_pwr_state = false; } #endif - /*TVout_LDO_ctrl(false); */ acc_dock_uevent(acc, false); } - acc_dock_psy(acc); } @@ -412,6 +479,8 @@ static irqreturn_t acc_dock_isr(int irq, void *ptr) { struct acc_con_info *acc = ptr; wake_lock(&acc->wake_lock); + ACC_CONDEV_DBG + ("A dock station attached or detached.."); acc_check_dock_detection(acc); wake_unlock(&acc->wake_lock); return IRQ_HANDLED; @@ -506,6 +575,48 @@ err_irq_dock: return ; } +static int acc_noti_univkbd_dock(struct sec_30pin_callbacks *cb, + unsigned int code) +{ + struct acc_con_info *acc = + container_of(cb, struct acc_con_info, callbacks); + + char *env_ptr; + char *stat_ptr; + char *envp[3]; + + ACC_CONDEV_DBG("universal keyboard noti. callback 0x%x", code); + + switch (code) { + case 0x68: /*dock is con*/ + acc_otg_enable_by_univkbd(acc, true); + acc->cable_type = POWER_SUPPLY_TYPE_DOCK; + acc->cable_sub_type = ONLINE_SUB_TYPE_KBD; + acc_dock_psy(acc); + break; + case 0x69: /*usb charging*/ + acc->cable_pwr_type = ONLINE_POWER_TYPE_USB; + acc_dock_psy(acc); + break; + case 0x6a: /*USB cable attached */ + acc_otg_enable_by_univkbd(acc, false); + acc->cable_pwr_type = ONLINE_POWER_TYPE_USB; + acc_dock_psy(acc); + break; + case 0x6b: /*TA connection*/ + acc->cable_pwr_type = ONLINE_POWER_TYPE_TA; + acc_dock_psy(acc); + break; + case 0x6c: /* USB cable detached */ + acc_otg_enable_by_univkbd(acc, true); + acc->cable_pwr_type = ONLINE_POWER_TYPE_BATTERY; + acc_dock_psy(acc); + break; + } + + return 0; +} + static void acc_dwork_accessory_detect(struct work_struct *work) { struct acc_con_info *acc = container_of(work, @@ -513,6 +624,7 @@ static void acc_dwork_accessory_detect(struct work_struct *work) int adc_val = 0; int acc_state = 0; + int acc_state2 = 0; acc_state = acc->pdata->get_acc_state(); @@ -520,9 +632,16 @@ static void acc_dwork_accessory_detect(struct work_struct *work) ACC_CONDEV_DBG("Accessory detached"); acc_accessory_uevent(acc, false); } else { - ACC_CONDEV_DBG("Accessory attached"); adc_val = acc_get_accessory_id(acc); + + acc_state2 = acc->pdata->get_acc_state(); + if (acc_state2) { + ACC_CONDEV_DBG("Accessory detached2."); + acc_accessory_uevent(acc, false); + } else { + ACC_CONDEV_DBG("Accessory attached"); acc_accessory_uevent(acc, adc_val); + } } } @@ -544,7 +663,7 @@ static int acc_con_probe(struct platform_device *pdev) } #ifdef CONFIG_REGULATOR -#ifndef CONFIG_MACH_P4NOTE +#if !defined(CONFIG_MACH_P4NOTE) && !defined(CONFIG_MACH_KONA) /* LDO1 regulator ON */ vadc_regulator = regulator_get(&pdev->dev, "vadc_3.3v"); if (IS_ERR(vadc_regulator)) { @@ -563,6 +682,7 @@ static int acc_con_probe(struct platform_device *pdev) acc->pdata = pdata; acc->current_dock = DOCK_NONE; acc->current_accessory = ACCESSORY_NONE; + acc->univ_kdb_accessory = ACCESSORY_NONE; #if defined(CONFIG_MHL_SII9234) || defined(CONFIG_SAMSUNG_MHL_9290) acc->mhl_irq = gpio_to_irq(pdata->mhl_irq_gpio); acc->mhl_pwr_state = false; @@ -580,6 +700,10 @@ static int acc_con_probe(struct platform_device *pdev) acc->padc = s3c_adc_register(pdev, NULL, NULL, 0); #endif + acc->callbacks.noti_univ_kdb_dock = acc_noti_univkbd_dock; + if (pdata->register_cb) + pdata->register_cb(&acc->callbacks); + #ifdef CONFIG_MHL_SII9234 retval = i2c_add_driver(&SII9234A_i2c_driver); if (retval) { diff --git a/drivers/accessory/sec_keyboard.c b/drivers/accessory/sec_keyboard.c index cc89c0c30f9..3e7556fc34c 100644 --- a/drivers/accessory/sec_keyboard.c +++ b/drivers/accessory/sec_keyboard.c @@ -44,6 +44,26 @@ static void sec_keyboard_remapkey(struct work_struct *work) data->remap_key = 0; } +static void sec_keyboard_ack(struct work_struct *work) +{ + unsigned int ackcode = 0; + char *envp[3]; + struct sec_keyboard_drvdata *data = container_of(work, + struct sec_keyboard_drvdata, ack_dwork.work); + + if (data->ack_code) { + ackcode = data->ack_code; + sec_keyboard_tx(data, ackcode); + } + + if (ackcode == 0x68) + data->univ_kbd_dock = true; + + printk(KERN_DEBUG "[Keyboard] Ack code to KBD 0x%x\n", ackcode); + + data->noti_univ_kbd_dock(data->ack_code); +} + static void release_all_keys(struct sec_keyboard_drvdata *data) { int i; @@ -105,7 +125,16 @@ static void sec_keyboard_process_data( data->pressed[scan_code] = true; schedule_delayed_work(&data->remap_dwork, HZ/3); break; - + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + data->ack_code = scan_code; + schedule_delayed_work(&data->ack_dwork, HZ/200); + printk(KERN_DEBUG "[Keyboard] scan_code %d Received.\n", + scan_code); + break; case 0xc5: case 0xc8: keycode = (scan_code & 0x7f); @@ -163,11 +192,15 @@ static int check_keyboard_dock(struct sec_keyboard_callbacks *cb, bool val) return 0; } } + /* To block acc_power enable in LPM mode */ + if ((data->tx_ready != true) && (val == true)) + return 0 ; } - if (!val) + if (!val) { data->dockconnected = false; - else { + data->univ_kbd_dock = false; + } else { cancel_delayed_work_sync(&data->power_dwork); /* wakeup by keyboard dock */ if (data->pre_connected) { @@ -304,7 +337,8 @@ static void keyboard_early_suspend(struct early_suspend *early_sus) msleep(20); */ release_all_keys(data); - sec_keyboard_tx(data, 0x10); /* the idle mode */ + if (data->univ_kbd_dock == false) + sec_keyboard_tx(data, 0x10); /* the idle mode */ } } @@ -350,16 +384,19 @@ static int __devinit sec_keyboard_probe(struct platform_device *pdev) ddata->led_on = false; ddata->dockconnected = false; ddata->pre_connected = false; + ddata->univ_kbd_dock = false; ddata->remap_key = 0; ddata->kl = UNKOWN_KEYLAYOUT; ddata->callbacks.check_keyboard_dock = check_keyboard_dock; if (pdata->register_cb) pdata->register_cb(&ddata->callbacks); + ddata->noti_univ_kbd_dock = pdata->noti_univ_kbd_dock; memcpy(ddata->keycode, sec_keycodes, sizeof(sec_keycodes)); INIT_DELAYED_WORK(&ddata->remap_dwork, sec_keyboard_remapkey); INIT_DELAYED_WORK(&ddata->power_dwork, sec_keyboard_power); + INIT_DELAYED_WORK(&ddata->ack_dwork, sec_keyboard_ack); platform_set_drvdata(pdev, ddata); input_set_drvdata(input, ddata); @@ -443,6 +480,7 @@ err_input_allocate_device: input_free_device(input); del_timer_sync(&ddata->remap_dwork.timer); del_timer_sync(&ddata->power_dwork.timer); + del_timer_sync(&ddata->ack_dwork.timer); err_free_mem: kfree(ddata); return error; diff --git a/drivers/accessory/sec_keyboard.h b/drivers/accessory/sec_keyboard.h index f5ccf5a24ee..e54ff30e0ef 100644 --- a/drivers/accessory/sec_keyboard.h +++ b/drivers/accessory/sec_keyboard.h @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/30pin_con.h> #include <linux/serio.h> +#include <linux/power_supply.h> #define KEYBOARD_SIZE 128 #define US_KEYBOARD 0xeb @@ -51,6 +52,7 @@ struct sec_keyboard_drvdata { struct device *keyboard_dev; struct delayed_work remap_dwork; struct delayed_work power_dwork; + struct delayed_work ack_dwork; struct sec_keyboard_callbacks callbacks; struct serio *serio; struct serio_driver serio_driver; @@ -59,16 +61,19 @@ struct sec_keyboard_drvdata { #endif void (*acc_power)(u8 token, bool active); void (*check_uart_path)(bool en); + int (*noti_univ_kbd_dock)(unsigned int code); bool led_on; bool dockconnected; bool pre_connected; bool pressed[KEYBOARD_SIZE]; bool pre_uart_path; bool tx_ready; + bool univ_kbd_dock; int acc_int_gpio; unsigned int remap_key; unsigned int kl; unsigned int pre_kl; + unsigned int ack_code; unsigned short keycode[KEYBOARD_SIZE]; unsigned long connected_time; unsigned long disconnected_time; diff --git a/drivers/irda/ir_remote_con_mc96.c b/drivers/irda/ir_remote_con_mc96.c index 5c624c8f861..9063137f19f 100644 --- a/drivers/irda/ir_remote_con_mc96.c +++ b/drivers/irda/ir_remote_con_mc96.c @@ -32,11 +32,12 @@ #include <linux/device.h> #include <linux/ir_remote_con_mc96.h> #include <linux/earlysuspend.h> -#include <linux/spinlock.h> #include "irda_fw.h" +#include <mach/gpio-rev00-p4notepq.h> #define MAX_SIZE 2048 #define MC96_READ_LENGTH 8 +#define DUMMY 0xffff #define USE_STOP_MODE @@ -45,7 +46,6 @@ struct ir_remocon_data { struct i2c_client *client; struct mc96_platform_data *pdata; struct early_suspend early_suspend; - spinlock_t lock; char signal[MAX_SIZE]; int length; int count; @@ -60,31 +60,45 @@ static void ir_remocon_early_suspend(struct early_suspend *h); static void ir_remocon_late_resume(struct early_suspend *h); #endif +static int count_number; +static int ack_number; +static int retry_count; +static int download_pass; + static int irda_fw_update(struct ir_remocon_data *ir_data) { struct ir_remocon_data *data = ir_data; struct i2c_client *client = data->client; - int i, ret; + int i, k, ret, ret2, checksum, checksum2; u8 buf_ir_test[8]; + msleep(20); data->pdata->ir_vdd_onoff(0); - data->pdata->ir_wake_en(1); + msleep(20); data->pdata->ir_vdd_onoff(1); + data->pdata->ir_wake_en(1); msleep(100); ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH); if (ret < 0) { - printk(KERN_ERR "1. %s: err %d\n", __func__, ret); + printk(KERN_ERR "%s: err %d\n", __func__, ret); ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH); - if (ret < 0) - goto err_i2c_fail; + if (ret < 0) { + printk(KERN_INFO "%s: broken FW!\n", __func__); + retry_count = 1; + } } ret = buf_ir_test[2] << 8 | buf_ir_test[3]; - if (ret < FW_VERSION) { + + if (ret == 0xffff) + ret = 0x202; + + if ((ret != FW_VERSION) || (retry_count != 0)) { printk(KERN_INFO "2. %s: chip : %04x, bin : %04x, need update!\n", __func__, ret, FW_VERSION); data->pdata->ir_vdd_onoff(0); data->pdata->ir_wake_en(0); + msleep(20); data->pdata->ir_vdd_onoff(1); msleep(100); @@ -94,11 +108,19 @@ static int irda_fw_update(struct ir_remocon_data *ir_data) ret = buf_ir_test[6] << 8 | buf_ir_test[7]; - if (ret == 0x01fe) - printk(KERN_INFO "4. %s: boot mode, FW download start\n", - __func__); - else + checksum = 0; + + for (k = 0; k < 6; k++) + checksum += buf_ir_test[k]; + + if (ret == checksum) + printk(KERN_INFO "%s: boot mode, FW download start! ret=%04x\n", + __func__, ret); + else { + printk(KERN_ERR "ABOV IC bootcode broken\n"); goto err_bootmode; + } + msleep(30); for (i = 0; i < FRAME_COUNT; i++) { @@ -121,41 +143,72 @@ static int irda_fw_update(struct ir_remocon_data *ir_data) printk(KERN_ERR "5. %s: err %d\n", __func__, ret); ret = buf_ir_test[6] << 8 | buf_ir_test[7]; + checksum = 0; + for (k = 0; k < 6; k++) + checksum += buf_ir_test[k]; + + msleep(20); + + ret2 = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH); + if (ret2 < 0) + printk(KERN_ERR "6. %s: err %d\n", __func__, ret2); + + ret2 = buf_ir_test[6] << 8 | buf_ir_test[7]; + for (k = 0; k < 6; k++) + checksum2 += buf_ir_test[k]; - if (ret == 0x02a3) - printk(KERN_INFO "6. %s: boot down complete\n", + if (ret == checksum) { + printk(KERN_INFO "1. %s: boot down complete\n", __func__); - else + download_pass = 1; + } else if (ret2 == checksum2) { + printk(KERN_INFO "2. %s: boot down complete\n", + __func__); + download_pass = 1; + } else { + retry_count++; + printk(KERN_ERR "FW Checksum fail. Retry = %d\n", + retry_count); goto err_bootmode; + } data->pdata->ir_vdd_onoff(0); - data->pdata->ir_wake_en(1); + msleep(20); data->pdata->ir_vdd_onoff(1); + data->pdata->ir_wake_en(1); msleep(60); ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH); ret = buf_ir_test[2] << 8 | buf_ir_test[3]; - printk(KERN_INFO "7. %s: user mode dev: %04x\n", __func__, ret); + printk(KERN_INFO "7. %s: user mode : Upgrade FW_version : %04x\n", + __func__, ret); + data->pdata->ir_wake_en(0); data->pdata->ir_vdd_onoff(0); data->on_off = 0; + msleep(100); } else { - printk(KERN_INFO "8. %s: chip : %04x, bin : %04x, latest FW_version now\n", + if (ret != DUMMY) + printk(KERN_INFO "8. %s: chip : %04x, bin : %04x, latest FW_ver\n", __func__, ret, FW_VERSION); data->pdata->ir_wake_en(0); data->pdata->ir_vdd_onoff(0); data->on_off = 0; + msleep(100); + + if (ret == FW_VERSION) + download_pass = 1; } return 0; -err_i2c_fail: - printk(KERN_ERR "%s: update fail! i2c ret : %x\n", - __func__, ret); err_update: printk(KERN_ERR "%s: update fail! count : %x, ret = %x\n", __func__, i, ret); + return ret; err_bootmode: - printk(KERN_ERR "%s: update fail, ret = %x\n", __func__, ret); + printk(KERN_ERR "%s: update fail, checksum = %x ret = %x\n", + __func__, checksum, ret); + data->pdata->ir_wake_en(0); data->pdata->ir_vdd_onoff(0); data->on_off = 0; return ret; @@ -165,9 +218,9 @@ static void irda_add_checksum_length(struct ir_remocon_data *ir_data, int count) { struct ir_remocon_data *data = ir_data; int i = 0, csum = 0; - +#if 0 printk(KERN_INFO "%s: length: %04x\n", __func__, count); - +#endif data->signal[0] = count >> 8; data->signal[1] = count & 0xff; @@ -191,8 +244,8 @@ static int irda_read_device_info(struct ir_remocon_data *ir_data) int ret; printk(KERN_INFO"%s called\n", __func__); - data->pdata->ir_wake_en(1); data->pdata->ir_vdd_onoff(1); + data->pdata->ir_wake_en(1); msleep(60); ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH); @@ -216,17 +269,22 @@ static void ir_remocon_work(struct ir_remocon_data *ir_data, int count) struct i2c_client *client = data->client; int buf_size = count+2; - int ret, i; + int ret; int sleep_timing; int end_data; int emission_time; - unsigned long flags; + int ack_pin_onoff; + + if (count_number >= 100) + count_number = 0; + + count_number++; printk(KERN_INFO "%s: total buf_size: %d\n", __func__, buf_size); irda_add_checksum_length(data, count); - spin_lock_irqsave(&data->lock, flags); + mutex_lock(&data->mutex); ret = i2c_master_send(client, data->signal, buf_size); if (ret < 0) { @@ -236,24 +294,57 @@ static void ir_remocon_work(struct ir_remocon_data *ir_data, int count) dev_err(&client->dev, "%s: err2 %d\n", __func__, ret); } - spin_unlock_irqrestore(&data->lock, flags); + mdelay(10); + + ack_pin_onoff = 0; + if (gpio_get_value(GPIO_IRDA_IRQ)) { + printk(KERN_INFO "%s : %d Checksum NG!\n", + __func__, count_number); + ack_pin_onoff = 1; + } else { + printk(KERN_INFO "%s : %d Checksum OK!\n", + __func__, count_number); + ack_pin_onoff = 2; + } + ack_number = ack_pin_onoff; + + mutex_unlock(&data->mutex); /* - for (i = 0; i < buf_size; i++) { + for (int i = 0; i < buf_size; i++) { printk(KERN_INFO "%s: data[%d] : 0x%02x\n", __func__, i, data->signal[i]); } */ data->count = 2; - end_data = data->signal[count-2] << 8 | data->signal[count-1]; emission_time = \ (1000 * (data->ir_sum - end_data) / (data->ir_freq)) + 10; sleep_timing = emission_time - 130; if (sleep_timing > 0) msleep(sleep_timing); +/* printk(KERN_INFO "%s: sleep_timing = %d\n", __func__, sleep_timing); +*/ + emission_time = \ + (1000 * (data->ir_sum) / (data->ir_freq)) + 50; + if (emission_time > 0) + msleep(emission_time); + printk(KERN_INFO "%s: emission_time = %d\n", + __func__, emission_time); + + if (gpio_get_value(GPIO_IRDA_IRQ)) { + printk(KERN_INFO "%s : %d Sending IR OK!\n", + __func__, count_number); + ack_pin_onoff = 4; + } else { + printk(KERN_INFO "%s : %d Sending IR NG!\n", + __func__, count_number); + ack_pin_onoff = 2; + } + + ack_number += ack_pin_onoff; #ifndef USE_STOP_MODE data->pdata->ir_vdd_onoff(0); data->on_off = 0; @@ -279,11 +370,12 @@ static ssize_t remocon_store(struct device *dev, struct device_attribute *attr, data->ir_freq = _data; if (data->on_off) { data->pdata->ir_wake_en(0); + udelay(200); data->pdata->ir_wake_en(1); - msleep(20); + msleep(30); } else { - data->pdata->ir_wake_en(1); data->pdata->ir_vdd_onoff(1); + data->pdata->ir_wake_en(1); msleep(60); data->on_off = 1; } @@ -328,7 +420,21 @@ static ssize_t remocon_show(struct device *dev, struct device_attribute *attr, return strlen(buf); } +static ssize_t remocon_ack(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ir_remocon_data *data = dev_get_drvdata(dev); + + printk(KERN_INFO "%s : ack_number = %d\n", __func__, ack_number); + + if (ack_number == 6) + return sprintf(buf, "1\n"); + else + return sprintf(buf, "0\n"); +} + static DEVICE_ATTR(ir_send, 0664, remocon_show, remocon_store); +static DEVICE_ATTR(ir_send_result, 0664, remocon_ack, NULL); static ssize_t check_ir_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -349,9 +455,9 @@ static int __devinit ir_remocon_probe(struct i2c_client *client, struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct ir_remocon_data *data; struct device *ir_remocon_dev; - int error; + int i, error; - printk(KERN_INFO "%s probe!\n", __func__); + printk(KERN_INFO "%s start!\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -EIO; @@ -366,16 +472,17 @@ static int __devinit ir_remocon_probe(struct i2c_client *client, data->client = client; data->pdata = client->dev.platform_data; - data->pdata->ir_remote_init(); mutex_init(&data->mutex); data->count = 2; data->on_off = 0; i2c_set_clientdata(client, data); - irda_fw_update(data); - - spin_lock_init(&data->lock); + for (i = 0; i < 6; i++) { + if (download_pass == 1) + break; + irda_fw_update(data); + } /* irda_read_device_info(data); */ @@ -388,6 +495,10 @@ static int __devinit ir_remocon_probe(struct i2c_client *client, pr_err("Failed to create device file(%s)!\n", dev_attr_ir_send.attr.name); + if (device_create_file(ir_remocon_dev, &dev_attr_ir_send_result) < 0) + pr_err("Failed to create device file(%s)!\n", + dev_attr_ir_send.attr.name); + if (device_create_file(ir_remocon_dev, &dev_attr_check_ir) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_check_ir.attr.name); diff --git a/drivers/misc/sec_jack.c b/drivers/misc/sec_jack.c index df77d33224b..550f894e580 100644 --- a/drivers/misc/sec_jack.c +++ b/drivers/misc/sec_jack.c @@ -44,7 +44,7 @@ /* keep this value if you support double-pressed concept */ #if defined(CONFIG_TARGET_LOCALE_KOR) #define SEND_KEY_CHECK_TIME_MS 20 /* 20ms - GB VOC in KOR*/ -#elif defined(CONFIG_MACH_Q1_BD) +#elif defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_P4NOTE) /* 27ms, total delay is approximately double more because hrtimer is called twice by gpio input driver, new sec spec total delay is 60ms +/-10ms */ diff --git a/drivers/power/max17042_fuelgauge_px.c b/drivers/power/max17042_fuelgauge_px.c index b8f02cbaf1a..1334db0a32a 100644 --- a/drivers/power/max17042_fuelgauge_px.c +++ b/drivers/power/max17042_fuelgauge_px.c @@ -387,6 +387,31 @@ static int fg_read_soc(void) return soc; } +static int fg_read_raw_soc(void) +{ + struct i2c_client *client = fg_i2c_client; + struct max17042_chip *chip = i2c_get_clientdata(client); + u8 data[2]; + u32 soc_lsb = 0; + int psoc = 0; + + if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) { + pr_err("%s: Failed to read SOCREP\n", __func__); + return -1; + } + + soc_lsb = (data[0] * 100) / 256; + psoc = (data[1] * 100) + soc_lsb; + chip->info.psoc = psoc; + + if (!(chip->info.pr_cnt % PRINT_COUNT)) + pr_info("%s: psoc(%d), vfsoc(%d)\n", __func__, + psoc, fg_read_vfsoc()); + + return psoc; +} + + static int fg_read_current(void) { struct i2c_client *client = fg_i2c_client; @@ -907,6 +932,27 @@ void fg_check_vf_fullcap_range(void) fg_read_register(DPACC_REG)); } +int fg_check_cap_corruption_p4(void) +{ + + struct i2c_client *client = fg_i2c_client; + struct max17042_chip *chip = i2c_get_clientdata(client); + + int designcap; + + /* If usgin Jig or low batt compensation flag is set, + then skip checking. */ + if (chip->pdata->check_jig_status()) { + fg_write_register(DESIGNCAP_REG, chip->info.vfcapacity - 1); + designcap = fg_read_register(DESIGNCAP_REG); + pr_info("%s: return by jig, vfcap(0x%04x), designcap(0x%04x)\n", + __func__, chip->info.vfcapacity, designcap); + return 0; + } else + return 1; +} + + int fg_check_cap_corruption(void) { struct i2c_client *client = fg_i2c_client; @@ -1621,6 +1667,9 @@ int get_fuelgauge_value(int data) ret = fg_read_voltage_now(); break; + case FG_RAW_LEVEL: + ret = fg_read_raw_soc(); + break; default: ret = -1; break; diff --git a/drivers/power/sec_battery_px.c b/drivers/power/sec_battery_px.c index 4787c9d3ca6..0a31772c22f 100644 --- a/drivers/power/sec_battery_px.c +++ b/drivers/power/sec_battery_px.c @@ -1043,11 +1043,12 @@ static int sec_bat_get_charging_status(struct battery_data *battery) { switch (battery->info.charging_source) { case CHARGER_BATTERY: - case CHARGER_USB: + //case CHARGER_USB: return POWER_SUPPLY_STATUS_DISCHARGING; case CHARGER_AC: case CHARGER_MISC: case CHARGER_DOCK: + case CHARGER_USB: if (battery->info.batt_is_full) return POWER_SUPPLY_STATUS_FULL; else if (battery->info.batt_improper_ta) diff --git a/drivers/sensor/lsm330dlc_accel.c b/drivers/sensor/lsm330dlc_accel.c index 5f228c788a0..430ef85df43 100644 --- a/drivers/sensor/lsm330dlc_accel.c +++ b/drivers/sensor/lsm330dlc_accel.c @@ -1045,15 +1045,25 @@ static int lsm330dlc_accel_probe(struct i2c_client *client, { struct lsm330dlc_accel_data *data; struct accel_platform_data *pdata; - int err = 0; + int err = 0, retry; + int probe_retry_max = 3; accel_dbgmsg("is started\n"); - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA | - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - pr_err("%s: i2c functionality check failed!\n", __func__); - err = -ENODEV; - goto exit; +probe_retry: + for (retry = 0; retry < 5; retry++) { + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + pr_err("%s: i2c functionality failed!\n", __func__); + + if (retry == 4) { + err = -ENODEV; + goto exit; + } + i2c_smbus_write_byte_data(client, CTRL_REG1, PM_OFF); + mdelay(2); + } else + break; } data = kzalloc(sizeof(struct lsm330dlc_accel_data), GFP_KERNEL); @@ -1315,6 +1325,12 @@ err_misc_register: err_read_reg: kfree(data); exit: + if (probe_retry_max > 0) { + pr_err("%s: Failed to probe..(%d try left)\n", + __func__, probe_retry_max); + probe_retry_max--; + goto probe_retry; + } return err; } diff --git a/drivers/sensor/sensors_core.c b/drivers/sensor/sensors_core.c index e003652ea8a..1813b9978cb 100644 --- a/drivers/sensor/sensors_core.c +++ b/drivers/sensor/sensors_core.c @@ -26,7 +26,6 @@ struct class *sensors_class; * sensors_classdev_register - create new sensor device in sensors_class. * @dev: The device to register. */ - static void set_sensor_attr(struct device *dev, struct device_attribute *attributes[]) { diff --git a/drivers/video/samsung/s3cfb_s6c1372.c b/drivers/video/samsung/s3cfb_s6c1372.c index 4d23708005e..1b0178595ca 100644 --- a/drivers/video/samsung/s3cfb_s6c1372.c +++ b/drivers/video/samsung/s3cfb_s6c1372.c @@ -74,7 +74,7 @@ static ssize_t lcdtype_show(struct device *dev, sprintf(temp, "SMD_S6F1202A02\n"); #else /*For p4*/ - sprintf(temp, "SMD_S6C1372\n"); + sprintf(temp, "SEC_LTL101AL01-002/003\n"); #endif strcat(buf, temp); return strlen(buf); |