diff options
author | sbrissen <sbrissen@hotmail.com> | 2013-06-21 07:40:19 -0400 |
---|---|---|
committer | Daniel Hillenbrand <codeworkx@cyanogenmod.org> | 2013-06-25 17:05:03 +0200 |
commit | cb93f68cb9ab19d9647962568b4c895548a869e8 (patch) | |
tree | 489bbfb6351db1d685e81c3d8c9c118544b68be4 /drivers/irda | |
parent | 5b3cb3ccc3df3b6106b5ae91f1ca77fcb1d99064 (diff) | |
download | kernel_samsung_smdk4412-cb93f68cb9ab19d9647962568b4c895548a869e8.zip kernel_samsung_smdk4412-cb93f68cb9ab19d9647962568b4c895548a869e8.tar.gz kernel_samsung_smdk4412-cb93f68cb9ab19d9647962568b4c895548a869e8.tar.bz2 |
smdk4412: add i925/p4noteltevzw support
Change-Id: I17d3befd6a6538c16db0675253927068a09085c6
Diffstat (limited to 'drivers/irda')
-rw-r--r-- | drivers/irda/ir_remote_con_mc96.c | 189 |
1 files changed, 150 insertions, 39 deletions
diff --git a/drivers/irda/ir_remote_con_mc96.c b/drivers/irda/ir_remote_con_mc96.c index 5c624c8..9063137 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); |