From fa4196c325e22f38409c9063e570665aa5a4d5e2 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 3 Sep 2010 22:16:14 +0800 Subject: [PATCH] add cmmb and commit code adapting raho board --- arch/arm/mach-rk2818/board-raho.c | 115 ++-- drivers/cmmb/cmmb_memory.c | 2 +- drivers/cmmb/siano/smscoreapi.c | 8 +- drivers/cmmb/siano/smsspiphy_rk.c | 29 +- drivers/fpga/spi_fpga_init.c | 2 +- drivers/input/gsensor/mma7660.c | 253 ++++---- drivers/input/misc/capella_cm3602.c | 61 +- drivers/input/touchscreen/ctp_it7250.c | 184 +++--- .../input/touchscreen/xpt2046_ts_320X480.c | 2 +- drivers/regulator/rk2818_lp8725.c | 121 ++++ drivers/rtc/alarm.c | 117 +++- drivers/rtc/rtc-s35392a.c | 563 ++++++++++++++++-- drivers/rtc/rtc-s35392a.h | 16 +- 13 files changed, 1090 insertions(+), 383 deletions(-) mode change 100644 => 100755 drivers/rtc/alarm.c diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c index 146c15c7d5c0..197e5c84b6e2 100644 --- a/arch/arm/mach-rk2818/board-raho.c +++ b/arch/arm/mach-rk2818/board-raho.c @@ -768,6 +768,7 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = { .type = "rtc-s35392a", .addr = 0x30, .flags = 0, + .irq = RK2818_PIN_PE2, }, #endif #if defined (CONFIG_FM_QN8006) @@ -824,9 +825,8 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = { * camera devices * author: ddl@rock-chips.com *****************************************************************************************/ -#ifdef CONFIG_VIDEO_RK2818 #define RK2818_CAM_POWER_PIN FPGA_PIO1_05//SPI_GPIO_P1_05 -#define RK2818_CAM_RESET_PIN FPGA_PIO1_14//SPI_GPIO_P1_14 +#define RK2818_CAM_RESET_PIN FPGA_PIO1_14//SPI_GPIO_P1_14 static int rk28_sensor_io_init(void); static int rk28_sensor_io_deinit(void); @@ -838,7 +838,6 @@ struct rk28camera_platform_data rk28_camera_platform_data = { { .gpio_reset = RK2818_CAM_RESET_PIN, .gpio_power = RK2818_CAM_POWER_PIN, - .gpio_flag = (RK28_CAM_POWERACTIVE_L|RK28_CAM_RESETACTIVE_L), .dev_name = "ov2655" }, { .gpio_reset = INVALID_GPIO, @@ -852,42 +851,36 @@ static int rk28_sensor_io_init(void) { int ret = 0, i; unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - unsigned int camera_ioflag; - - //printk("\n%s....%d ******** ddl *********\n",__FUNCTION__,__LINE__); - for (i=0; i<2; i++) { + printk("\n%s....%d ******** ddl *********\n",__FUNCTION__,__LINE__); + + for (i=0; i<2; i++) { camera_reset = rk28_camera_platform_data.gpio_res[i].gpio_reset; - camera_power = rk28_camera_platform_data.gpio_res[i].gpio_power; - camera_ioflag = rk28_camera_platform_data.gpio_res[i].gpio_flag; - - if (camera_power != INVALID_GPIO) { + camera_power = rk28_camera_platform_data.gpio_res[i].gpio_power; + + if (camera_power != INVALID_GPIO) { ret = gpio_request(camera_power, "camera power"); if (ret) continue; - - gpio_set_value(camera_reset, (((~camera_ioflag)&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - gpio_direction_output(camera_power, (((~camera_ioflag)&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - - //printk("\n%s....%d %x ******** ddl *********\n",__FUNCTION__,__LINE__,(((~camera_ioflag)&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); + + gpio_set_value(camera_reset, 1); + gpio_direction_output(camera_power, 0); } - + if (camera_reset != INVALID_GPIO) { ret = gpio_request(camera_reset, "camera reset"); if (ret) { - if (camera_power != INVALID_GPIO) - gpio_free(camera_power); + if (camera_power != INVALID_GPIO) + gpio_free(camera_power); continue; } - gpio_set_value(camera_reset, ((camera_ioflag&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); - gpio_direction_output(camera_reset, ((camera_ioflag&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); - - //printk("\n%s....%d %x ******** ddl *********\n",__FUNCTION__,__LINE__,((camera_ioflag&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); + gpio_set_value(camera_reset, 0); + gpio_direction_output(camera_reset, 0); } } - + return 0; } @@ -896,20 +889,20 @@ static int rk28_sensor_io_deinit(void) unsigned int i; unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - //printk("\n%s....%d ******** ddl *********\n",__FUNCTION__,__LINE__); - - for (i=0; i<2; i++) { + printk("\n%s....%d ******** ddl *********\n",__FUNCTION__,__LINE__); + + for (i=0; i<2; i++) { camera_reset = rk28_camera_platform_data.gpio_res[i].gpio_reset; - camera_power = rk28_camera_platform_data.gpio_res[i].gpio_power; - + camera_power = rk28_camera_platform_data.gpio_res[i].gpio_power; + if (camera_power != INVALID_GPIO){ gpio_direction_input(camera_power); - gpio_free(camera_power); + gpio_free(camera_power); } - + if (camera_reset != INVALID_GPIO) { gpio_direction_input(camera_reset); - gpio_free(camera_reset); + gpio_free(camera_reset); } } @@ -920,37 +913,28 @@ static int rk28_sensor_io_deinit(void) static int rk28_sensor_power(struct device *dev, int on) { unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - unsigned int camera_ioflag; - + if(rk28_camera_platform_data.gpio_res[0].dev_name && (strcmp(rk28_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) { camera_reset = rk28_camera_platform_data.gpio_res[0].gpio_reset; camera_power = rk28_camera_platform_data.gpio_res[0].gpio_power; - camera_ioflag = rk28_camera_platform_data.gpio_res[0].gpio_flag; } else if (rk28_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk28_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) { camera_reset = rk28_camera_platform_data.gpio_res[1].gpio_reset; camera_power = rk28_camera_platform_data.gpio_res[1].gpio_power; - camera_ioflag = rk28_camera_platform_data.gpio_res[1].gpio_flag; } if (camera_reset != INVALID_GPIO) { - gpio_set_value(camera_reset, ((camera_ioflag&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); - //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); + gpio_set_value(camera_reset, !on); + //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev),camera_reset, on); } - if (camera_power != INVALID_GPIO) { - if (on) { - gpio_set_value(camera_power, ((camera_ioflag&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - } else { - gpio_set_value(camera_power, (((~camera_ioflag)&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK28_CAM_POWERACTIVE_MASK)>>RK28_CAM_POWERACTIVE_BITPOS)); - } - + if (camera_power != INVALID_GPIO) { + gpio_set_value(camera_power, !on); + printk("\n%s..%s..PowerPin=%d ..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev), camera_power, !on); } if (camera_reset != INVALID_GPIO) { msleep(3); /* delay 3 ms */ - gpio_set_value(camera_reset,(((~camera_ioflag)&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); - //printk("\n%s..%s..ResetPin= %d..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK28_CAM_RESETACTIVE_MASK)>>RK28_CAM_RESETACTIVE_BITPOS)); - } + gpio_set_value(camera_reset,on); + printk("\n%s..%s..ResetPin= %d..PinLevel = %x ******** ddl *********\n",__FUNCTION__,dev_name(dev), camera_reset, on); + } return 0; } @@ -973,7 +957,6 @@ struct soc_camera_link rk2818_iclink = { .module_name = "ov2655", #endif }; -#endif /***************************************************************************************** * battery devices @@ -1612,25 +1595,33 @@ struct platform_device rk28_device_headset = { #endif #ifdef CONFIG_INPUT_LPSENSOR_CM3602 +static int capella_cm3602_power(int on); + +static struct capella_cm3602_platform_data capella_cm3602_pdata = { + .power = capella_cm3602_power, + .irq_pin = FPGA_PIO0_04, + .pwd_out_pin = FPGA_PIO4_07, + .ps_shutdown_pin = FPGA_PIO5_00, + //.p_out = MAHIMAHI_GPIO_PROXIMITY_INT_N + }; + static int capella_cm3602_power(int on) { /* TODO eolsen Add Voltage reg control */ if (on) { - // gpio_direction_output(MAHIMAHI_GPIO_PROXIMITY_EN, 0); + printk("[%s]:on---\n",__FUNCTION__); + gpio_direction_output(capella_cm3602_pdata.pwd_out_pin, SPI_GPIO_OUT); + gpio_set_value(capella_cm3602_pdata.pwd_out_pin, SPI_GPIO_LOW); //CM3605_PWD output + gpio_direction_output(capella_cm3602_pdata.ps_shutdown_pin, SPI_GPIO_OUT); + gpio_set_value(capella_cm3602_pdata.ps_shutdown_pin, SPI_GPIO_LOW); //CM3605_PS_SHUTDOWN } - else { - // gpio_direction_output(MAHIMAHI_GPIO_PROXIMITY_EN, 1); + else { + printk("[%s]:off---\n",__FUNCTION__); + gpio_set_value(capella_cm3602_pdata.pwd_out_pin, SPI_GPIO_HIGH); + gpio_set_value(capella_cm3602_pdata.ps_shutdown_pin, SPI_GPIO_HIGH); } return 0; } -static struct capella_cm3602_platform_data capella_cm3602_pdata = { - .power = capella_cm3602_power, - .irq_pin = SPI_GPIO_P6_04, - .pwd_out_pin = SPI_GPIO_P4_07, - .ps_shutdown_pin = SPI_GPIO_P4_08, - //.p_out = MAHIMAHI_GPIO_PROXIMITY_INT_N - }; - struct platform_device rk2818_device_cm3605 = { .name = CAPELLA_CM3602, .id = -1, diff --git a/drivers/cmmb/cmmb_memory.c b/drivers/cmmb/cmmb_memory.c index f476877b877e..8d77d2cc7d30 100755 --- a/drivers/cmmb/cmmb_memory.c +++ b/drivers/cmmb/cmmb_memory.c @@ -398,7 +398,7 @@ static long cmmbmemo_ioctl(struct file *file, unsigned int cmd, unsigned long ar break; case CMMB_GET_AUDIO_TYPE:{ - return cmmbmemo->videotype; + return cmmbmemo->audiotype; } break; diff --git a/drivers/cmmb/siano/smscoreapi.c b/drivers/cmmb/siano/smscoreapi.c index 150cbc34bb7d..c26043c67cbb 100755 --- a/drivers/cmmb/siano/smscoreapi.c +++ b/drivers/cmmb/siano/smscoreapi.c @@ -50,8 +50,8 @@ #endif // to enable log -int sms_debug =7; -//int sms_debug =0; //hzb 0526 +//int sms_debug =7; +int sms_debug =0; //hzb 0526 // for loopback char g_LbResBuf[256]={0}; // @@ -1173,8 +1173,8 @@ void smscore_onresponse(struct smscore_device_t *coredev, //sms_debug("client=0x %x\n", client); rc = client->onresponse_handler(client->context, cb); } - sms_debug("onresponse_handler ret = 0x%x\n", rc); - sms_debug("phdr->msgType %d\n", phdr->msgType); + //sms_debug("onresponse_handler ret = 0x%x\n", rc); + // sms_debug("phdr->msgType %d\n", phdr->msgType); diff --git a/drivers/cmmb/siano/smsspiphy_rk.c b/drivers/cmmb/siano/smsspiphy_rk.c index b61128a2c718..15b20d8694f8 100755 --- a/drivers/cmmb/siano/smsspiphy_rk.c +++ b/drivers/cmmb/siano/smsspiphy_rk.c @@ -40,7 +40,7 @@ along with this program. If not, see . #include #include "smscoreapi.h" - +#include #define SSP_PORT 1 @@ -305,7 +305,7 @@ static irqreturn_t spibus_interrupt(int irq, void *context) u_irq_count ++; // PDEBUG("INT counter = %d\n", u_irq_count); - printk("cmmb siano 1186 int\n"); + //printk("cmmb siano 1186 int\n"); sms_info("spibus_interrupt %d\n", u_irq_count); if (spiphy_dev->interruptHandler) @@ -356,7 +356,7 @@ void smsspibus_xfer(void *context, unsigned char *txbuf, if(txbuf) { - sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]); + // sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]); ret = spi_write(spiphy_dev->Smsdevice, txbuf, len); @@ -370,7 +370,7 @@ void smsspibus_xfer(void *context, unsigned char *txbuf, if ((rxbuf)&&(len != 16)) ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len); - sms_debug("rxbuf 4, 5,6,7,8,9=%x,%x,%x,%x,%x,%x\n",rxbuf[4],rxbuf[5],rxbuf[6],rxbuf[7],rxbuf[8],rxbuf[9]); + // sms_debug("rxbuf 4, 5,6,7,8,9=%x,%x,%x,%x,%x,%x\n",rxbuf[4],rxbuf[5],rxbuf[6],rxbuf[7],rxbuf[8],rxbuf[9]); //sms_debug("sms spi read buf=0x%x\n",rxbuf[5]); } @@ -398,7 +398,8 @@ void smsspibus_ssp_suspend(void* context ) //ssp_disable(&(spiphy_dev->sspdev)); //ssp_exit(&spiphy_dev->sspdev); free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev); - +//zyc + gpio_direction_output(CMMB_1186_SPIIRQ,0); /* release DMA resources */ //if (spiphy_dev->rx_dma_channel >= 0) //pxa_free_dma(spiphy_dev->rx_dma_channel); @@ -429,7 +430,8 @@ static void chip_poweron() #endif //1186 cmmb power on - +//set the SPI CS mode , zyc + //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1); gpio_direction_output(CMMB_1186_POWER_RESET,0); gpio_direction_output(CMMB_1186_POWER_DOWN,0); @@ -471,6 +473,10 @@ static void chip_powerdown() //1186 cmmb power down #if 1 gpio_direction_output(CMMB_1186_POWER_ENABLE,0); +//set the CS0 as gpio mode + +// rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0); +// gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0); printk("cmmb chip_powerdown !!!!\n"); @@ -494,7 +500,10 @@ int smsspibus_ssp_resume(void* context) chip_poweron(); free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev); //printk("siano 1186 request irq\n"); - gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullDown); +// spiirqgpio low , PULLUP , zyc + gpio_direction_output(CMMB_1186_SPIIRQ,0); + gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp); + //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev); request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev); if(ret<0){ @@ -534,6 +543,8 @@ void *smsspiphy_init(void *context, void (*smsspi_interruptHandler)(void *),void spiphy_dev->Smsdevice = (struct spi_device*)context; //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING); +//set IRO GPIO as gpio mode ,zyc + //rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME,0); error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq"); if (error) { //dev_err(&pdev->dev, "failed to request play key gpio\n"); @@ -551,7 +562,11 @@ void *smsspiphy_init(void *context, void (*smsspi_interruptHandler)(void *),void #endif //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);// + +//zyc + gpio_direction_output(CMMB_1186_SPIIRQ,0); gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp); + //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev); request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev); diff --git a/drivers/fpga/spi_fpga_init.c b/drivers/fpga/spi_fpga_init.c index 71bc6c7fae7d..56cb280fc2df 100755 --- a/drivers/fpga/spi_fpga_init.c +++ b/drivers/fpga/spi_fpga_init.c @@ -543,7 +543,7 @@ static int __devinit spi_fpga_probe(struct spi_device * spi) INIT_LIST_HEAD(&port->trans_queue); #endif - spi_fpga_rst(); + //spi_fpga_rst(); sprintf(b, "fpga_irq_workqueue"); port->fpga_irq_workqueue = create_freezeable_workqueue(b); if (!port->fpga_irq_workqueue) { diff --git a/drivers/input/gsensor/mma7660.c b/drivers/input/gsensor/mma7660.c index d475f4023be6..eb2cfb00db3e 100755 --- a/drivers/input/gsensor/mma7660.c +++ b/drivers/input/gsensor/mma7660.c @@ -43,11 +43,12 @@ static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id #define MMA7660_SPEED 200 * 1000 /* Addresses to scan -- protected by sense_data_mutex */ -static char sense_data[RBUFF_SIZE + 1]; +//static char sense_data[RBUFF_SIZE + 1]; static struct i2c_client *this_client; +static struct miscdevice mma7660_device; static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq); -static atomic_t data_ready; + #ifdef CONFIG_ANDROID_POWER static android_early_suspend_t mma7660_early_suspend; #endif @@ -96,23 +97,23 @@ err: return ret ; } -static int mma7660_rx_data(char *rxData, int length) +static int mma7660_rx_data(struct i2c_client *client, char *rxData, int length) { int ret = 0; char reg = rxData[0]; - ret = i2c_master_reg8_recv(this_client, reg, rxData, length, MMA7660_SPEED); + ret = i2c_master_reg8_recv(client, reg, rxData, length, MMA7660_SPEED); return (ret > 0)? 0 : ret; } -static int mma7660_tx_data(char *txData, int length) +static int mma7660_tx_data(struct i2c_client *client, char *txData, int length) { int ret = 0; char reg = txData[0]; - ret = i2c_master_reg8_send(this_client, reg, &txData[1], length-1, MMA7660_SPEED); + ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, MMA7660_SPEED); return (ret > 0)? 0 : ret; } -static int mma7660_set_rate(char rate) +static int mma7660_set_rate(struct i2c_client *client, char rate) { char buffer[2]; int ret = 0; @@ -129,71 +130,75 @@ static int mma7660_set_rate(char rate) buffer[0] = MMA7660_REG_SR; buffer[1] = 0xf8 | (0x07 & (~i)); - ret = mma7660_tx_data(&(buffer[0]), 2); - ret = mma7660_rx_data(&(buffer[0]), 1); + ret = mma7660_tx_data(client, &(buffer[0]), 2); + ret = mma7660_rx_data(client, &(buffer[0]), 1); return ret; } -static int mma7660_start_dev(char rate) +static int mma7660_start_dev(struct i2c_client *client, char rate) { char buffer[MMA7660_REG_LEN]; int ret = 0; buffer[0] = MMA7660_REG_INTSU; buffer[1] = 0x10; //0x10; modify by zhao - ret = mma7660_tx_data(&buffer[0], 2); - ret = mma7660_rx_data(&buffer[0], 1); + ret = mma7660_tx_data(client, &buffer[0], 2); + ret = mma7660_rx_data(client, &buffer[0], 1); - ret = mma7660_set_rate(rate); + ret = mma7660_set_rate(client, rate); buffer[0] = MMA7660_REG_MODE; - buffer[1] = 0x81; - ret = mma7660_tx_data(&buffer[0], 2); - ret = mma7660_rx_data(&buffer[0], 1); + buffer[1] = 0x01; + ret = mma7660_tx_data(client, &buffer[0], 2); + ret = mma7660_rx_data(client, &buffer[0], 1); - enable_irq(this_client->irq); + enable_irq(client->irq); rk28printk("\n----------------------------mma7660_start------------------------\n"); return ret; } -static int mma7660_start(char rate) +static int mma7660_start(struct i2c_client *client, char rate) { - struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client); + struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - if (mma->status == MMA7660_OPEN) { + if (mma7660->status == MMA7660_OPEN) { return 0; } - mma->status = MMA7660_OPEN; - return mma7660_start_dev(rate); + mma7660->status = MMA7660_OPEN; + return mma7660_start_dev(client, rate); } -static int mma7660_close_dev(void) +static int mma7660_close_dev(struct i2c_client *client) { char buffer[2]; - + + disable_irq_nosync(client->irq); + buffer[0] = MMA7660_REG_MODE; buffer[1] = 0x00; - return mma7660_tx_data(buffer, 2); + return mma7660_tx_data(client, buffer, 2); } -static int mma7660_close(void) +static int mma7660_close(struct i2c_client *client) { - struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client); + struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - mma->status = MMA7660_CLOSE; + mma7660->status = MMA7660_CLOSE; - return mma7660_close_dev(); + return mma7660_close_dev(client); } -static int mma7660_reset_rate(char rate) +static int mma7660_reset_rate(struct i2c_client *client, char rate) { int ret = 0; - ret = mma7660_close_dev(); - ret = mma7660_start_dev(rate); + rk28printk("\n----------------------------mma7660_reset_rate------------------------\n"); + + ret = mma7660_close_dev(client); + ret = mma7660_start_dev(client, rate); return ret ; } @@ -211,37 +216,32 @@ static inline int mma7660_convert_to_int(char value) return result; } -static void mma7660_report_value(short *rbuf) +static void mma7660_report_value(struct i2c_client *client, struct mma7660_axis *axis) { - struct mma7660_data *data = i2c_get_clientdata(this_client); - struct mma7660_axis *axis = (struct mma7660_axis *)rbuf; + struct mma7660_data *mma7660 = i2c_get_clientdata(client); + //struct mma7660_axis *axis = (struct mma7660_axis *)rbuf; /* Report acceleration sensor information */ - input_report_abs(data->input_dev, ABS_X, axis->x); - input_report_abs(data->input_dev, ABS_Y, axis->y); - input_report_abs(data->input_dev, ABS_Z, axis->z); - input_sync(data->input_dev); + input_report_abs(mma7660->input_dev, ABS_X, axis->x); + input_report_abs(mma7660->input_dev, ABS_Y, axis->y); + input_report_abs(mma7660->input_dev, ABS_Z, axis->z); + input_sync(mma7660->input_dev); rk28printk("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z); } -static int mma7660_get_data(void) +static int mma7660_get_data(struct i2c_client *client) { char buffer[3]; int ret; struct mma7660_axis axis; - memset(buffer, 0, 3); - buffer[0] = MMA7660_REG_X_OUT; - ret = mma7660_rx_data(&buffer[0], 3); - //while(mma7660_rx_data(&buffer[0], 3)); - /* - if (!ret) { - rk28printk( "%s: -------------------------------------------gsensor device register = [0]:%d [1]:%d [2]:%d [3]:0x%x [4]:0x%x [5]:0x%x [6]:0x%x [7]:0x%x-----------------------------------------------\n", - __func__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); - } - */ - if (ret < 0) - return ret; + do { + memset(buffer, 0, 3); + buffer[0] = MMA7660_REG_X_OUT; + ret = mma7660_rx_data(client, &buffer[0], 3); + if (ret < 0) + return ret; + } while ((buffer[0] & 0x40) || (buffer[1] & 0x40) || (buffer[2] & 0x40)); axis.x = mma7660_convert_to_int(buffer[MMA7660_REG_X_OUT]); axis.y = -mma7660_convert_to_int(buffer[MMA7660_REG_Y_OUT]); @@ -250,14 +250,15 @@ static int mma7660_get_data(void) //rk28printk( "%s: ------------------mma7660_GetData axis = %d %d %d--------------\n", // __func__, axis.x, axis.y, axis.z); - memcpy(sense_data, &axis, sizeof(axis)); - mma7660_report_value(sense_data); + //memcpy(sense_data, &axis, sizeof(axis)); + mma7660_report_value(client, &axis); //atomic_set(&data_ready, 0); //wake_up(&data_ready_wq); return 0; } +/* static int mma7660_trans_buff(char *rbuf, int size) { //wait_event_interruptible_timeout(data_ready_wq, @@ -270,10 +271,10 @@ static int mma7660_trans_buff(char *rbuf, int size) return 0; } +*/ static int mma7660_open(struct inode *inode, struct file *file) { - rk28printk("----------------------------mma7660_open------------------------\n"); return 0;//nonseekable_open(inode, file); } @@ -290,8 +291,7 @@ static int mma7660_ioctl(struct inode *inode, struct file *file, unsigned int cm char msg[RBUFF_SIZE + 1]; int ret = -1; char rate; - - rk28printk("----------------------------mma7660_ioctl------------------------cmd: %d\n", cmd); + struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); switch (cmd) { case ECS_IOCTL_APP_SET_RATE: @@ -304,25 +304,27 @@ static int mma7660_ioctl(struct inode *inode, struct file *file, unsigned int cm switch (cmd) { case ECS_IOCTL_START: - ret = mma7660_start(MMA7660_RATE_32); + ret = mma7660_start(client, MMA7660_RATE_32); if (ret < 0) return ret; break; case ECS_IOCTL_CLOSE: - ret = mma7660_close(); + ret = mma7660_close(client); if (ret < 0) return ret; break; case ECS_IOCTL_APP_SET_RATE: - ret = mma7660_reset_rate(rate); + ret = mma7660_reset_rate(client, rate); if (ret < 0) return ret; break; + /* case ECS_IOCTL_GETDATA: ret = mma7660_trans_buff(msg, RBUFF_SIZE); if (ret < 0) return ret; break; + */ default: return -ENOTTY; } @@ -341,29 +343,33 @@ static int mma7660_ioctl(struct inode *inode, struct file *file, unsigned int cm static void mma7660_work_func(struct work_struct *work) { - if (mma7660_get_data() < 0) + struct mma7660_data *mma7660 = container_of(work, struct mma7660_data, work); + struct i2c_client *client = mma7660->client; + + if (mma7660_get_data(client) < 0) rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n"); - enable_irq(this_client->irq); - rk28printk("---------------------------------------mma7660_work_func----------------------------------\n"); + enable_irq(client->irq); } -static void mma7660_delaywork_func(struct work_struct *work) +static void mma7660_delaywork_func(struct work_struct *work) { - - if (mma7660_get_data() < 0) - rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n"); - enable_irq(this_client->irq); - //rk28printk("---------------------------------------mma7660_delaywork_func------------------------------\n"); + struct delayed_work *delaywork = container_of(work, struct delayed_work, work); + struct mma7660_data *mma7660 = container_of(delaywork, struct mma7660_data, delaywork); + struct i2c_client *client = mma7660->client; + if (mma7660_get_data(client) < 0) + rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n"); + + enable_irq(client->irq); } static irqreturn_t mma7660_interrupt(int irq, void *dev_id) { - struct mma7660_data *data = dev_id; - disable_irq_nosync(this_client->irq); - schedule_delayed_work(&data->delaywork,msecs_to_jiffies(30)); - //rk28printk("--------------------------------------mma7660_interrupt---------------------------------------\n"); + struct mma7660_data *mma7660 = (struct mma7660_data *)dev_id; + + disable_irq_nosync(irq); + schedule_delayed_work(&mma7660->delaywork, msecs_to_jiffies(30)); return IRQ_HANDLED; } @@ -383,13 +389,13 @@ static struct miscdevice mma7660_device = { static int mma7660_remove(struct i2c_client *client) { - struct mma7660_data *mma = i2c_get_clientdata(client); + struct mma7660_data *mma7660 = i2c_get_clientdata(client); misc_deregister(&mma7660_device); - input_unregister_device(mma->input_dev); - input_free_device(mma->input_dev); - free_irq(client->irq, mma); - kfree(mma); + input_unregister_device(mma7660->input_dev); + input_free_device(mma7660->input_dev); + free_irq(client->irq, mma7660); + kfree(mma7660); #ifdef CONFIG_ANDROID_POWER android_unregister_early_suspend(&mma7660_early_suspend); #endif @@ -400,32 +406,30 @@ static int mma7660_remove(struct i2c_client *client) #ifdef CONFIG_ANDROID_POWER static int mma7660_suspend(android_early_suspend_t *h) { + struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); rk28printk("Gsensor mma7760 enter suspend\n"); - return mma7660_close_dev(); + return mma7660_close_dev(client); } static int mma7660_resume(android_early_suspend_t *h) { - struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client); + struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); + struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); rk28printk("Gsensor mma7760 resume!!\n"); - return mma7660_start_dev(mma->curr_tate); + return mma7660_start_dev(mma7660->curr_tate); } -/* -static int suspend(struct i2c_client *client, pm_message_t mesg) +#else +static int mma7660_suspend(struct i2c_client *client, pm_message_t mesg) { rk28printk("Gsensor mma7760 enter 2 level suspend\n"); - return mma7660_close_dev(); + return mma7660_close_dev(client); } -static int resume(struct i2c_client *client) +static int mma7660_resume(struct i2c_client *client) { - struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client); + struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); rk28printk("Gsensor mma7760 2 level resume!!\n"); - return mma7660_start_dev(mma->curr_tate); + return mma7660_start_dev(client, mma7660->curr_tate); } -*/ -#else -#define mma7660_suspend NULL -#define mma7660_resume NULL #endif static const struct i2c_device_id mma7660_id[] = { @@ -440,16 +444,18 @@ static struct i2c_driver mma7660_driver = { .id_table = mma7660_id, .probe = mma7660_probe, .remove = __devexit_p(mma7660_remove), - //.suspend = &suspend, - //.resume = &resume, +#ifndef CONFIG_ANDROID_POWER + .suspend = &mma7660_suspend, + .resume = &mma7660_resume, +#endif }; static int mma7660_init_client(struct i2c_client *client) { - struct mma7660_data *data; + struct mma7660_data *mma7660; int ret; - data = i2c_get_clientdata(client); + mma7660 = i2c_get_clientdata(client); rk28printk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq)); if ( !gpio_is_valid(client->irq)) { rk28printk("+++++++++++gpio_is_invalid\n"); @@ -460,8 +466,14 @@ static int mma7660_init_client(struct i2c_client *client) rk28printk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq)); return ret; } + ret = gpio_direction_input(client->irq); + if (ret) { + rk28printk("failed to set mma7990_trig GPIO gpio input\n"); + return ret; + } + gpio_pull_updown(client->irq, GPIOPullUp); client->irq = gpio_to_irq(client->irq); - ret = request_irq(client->irq, mma7660_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, client->dev.driver->name, data); + ret = request_irq(client->irq, mma7660_interrupt, IRQF_TRIGGER_LOW, client->dev.driver->name, mma7660); rk28printk("request irq is %d,ret is 0x%x\n",client->irq,ret); if (ret ) { rk28printk(KERN_ERR "mma7660_init_client: request irq failed,ret is %d\n",ret); @@ -475,21 +487,21 @@ static int mma7660_init_client(struct i2c_client *client) static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct mma7660_data *mma; + struct mma7660_data *mma7660; int err; - mma = kzalloc(sizeof(struct mma7660_data), GFP_KERNEL); - if (!mma) { + mma7660 = kzalloc(sizeof(struct mma7660_data), GFP_KERNEL); + if (!mma7660) { rk28printk("[mma7660]:alloc data failed.\n"); err = -ENOMEM; goto exit_alloc_data_failed; } + + INIT_WORK(&mma7660->work, mma7660_work_func); + INIT_DELAYED_WORK(&mma7660->delaywork, mma7660_delaywork_func); - INIT_WORK(&mma->work, mma7660_work_func); - INIT_DELAYED_WORK(&mma->delaywork, mma7660_delaywork_func); - - mma->client = client; - i2c_set_clientdata(client, mma); + mma7660->client = client; + i2c_set_clientdata(client, mma7660); this_client = client; @@ -500,33 +512,34 @@ static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id goto exit_request_gpio_irq_failed; } - mma->input_dev = input_allocate_device(); - if (!mma->input_dev) { + mma7660->input_dev = input_allocate_device(); + if (!mma7660->input_dev) { err = -ENOMEM; rk28printk(KERN_ERR "mma7660_probe: Failed to allocate input device\n"); goto exit_input_allocate_device_failed; } - set_bit(EV_ABS, mma->input_dev->evbit); + set_bit(EV_ABS, mma7660->input_dev->evbit); /* x-axis acceleration */ - input_set_abs_params(mma->input_dev, ABS_X, -1500, 1500, 0, 0); + input_set_abs_params(mma7660->input_dev, ABS_X, -1500, 1500, 0, 0); /* y-axis acceleration */ - input_set_abs_params(mma->input_dev, ABS_Y, -1500, 1500, 0, 0); + input_set_abs_params(mma7660->input_dev, ABS_Y, -1500, 1500, 0, 0); /* z-axis acceleration */ - input_set_abs_params(mma->input_dev, ABS_Z, -1500, 1500, 0, 0); + input_set_abs_params(mma7660->input_dev, ABS_Z, -1500, 1500, 0, 0); - mma->input_dev->name = "compass"; + mma7660->input_dev->name = "compass"; - err = input_register_device(mma->input_dev); + err = input_register_device(mma7660->input_dev); if (err < 0) { rk28printk(KERN_ERR "mma7660_probe: Unable to register input device: %s\n", - mma->input_dev->name); + mma7660->input_dev->name); goto exit_input_register_device_failed; } + mma7660_device.parent = &client->dev; err = misc_register(&mma7660_device); if (err < 0) { rk28printk(KERN_ERR @@ -548,20 +561,22 @@ static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id android_register_early_suspend(&mma7660_early_suspend); #endif rk28printk(KERN_INFO "mma7660 probe ok\n"); - mma->status = -1; - //mma7660_start(MMA7660_RATE_32); + mma7660->status = -1; +#if 0 + mma7660_start(client, MMA7660_RATE_32); +#endif return 0; exit_gsensor_sysfs_init_failed: misc_deregister(&mma7660_device); exit_misc_device_register_mma7660_device_failed: - input_unregister_device(mma->input_dev); + input_unregister_device(mma7660->input_dev); exit_input_register_device_failed: - input_free_device(mma->input_dev); + input_free_device(mma7660->input_dev); exit_input_allocate_device_failed: - free_irq(client->irq, mma); + free_irq(client->irq, mma7660); exit_request_gpio_irq_failed: - kfree(mma); + kfree(mma7660); exit_alloc_data_failed: ; return err; diff --git a/drivers/input/misc/capella_cm3602.c b/drivers/input/misc/capella_cm3602.c index 7863d8df2d61..1788ba7de1f7 100755 --- a/drivers/input/misc/capella_cm3602.c +++ b/drivers/input/misc/capella_cm3602.c @@ -29,7 +29,11 @@ #include #include +#if 0 #define D(x...) printk(x) +#else +#define D(x...) +#endif static struct capella_cm3602_data { struct input_dev *input_dev; @@ -42,7 +46,7 @@ static struct capella_cm3602_data { static int misc_opened; -static bool time_enable = true; +static bool time_enable = false; static int capella_cm3602_report(struct capella_cm3602_data *data) { @@ -63,11 +67,12 @@ static int capella_cm3602_report(struct capella_cm3602_data *data) static irqreturn_t capella_cm3602_irq_handler(int irq, void *data) { struct capella_cm3602_data *ip = data; - printk("------------------capella_cm3602_irq_handler------------\n"); + printk("---capella_cm3602_irq_handler----\n"); //int val = capella_cm3602_report(ip); input_report_abs(ip->input_dev, ABS_DISTANCE, 0); input_sync(ip->input_dev); - add_timer(&ip->cm3602_timer); + //printk("input_report_abs=0\n"); + //add_timer(&ip->cm3602_timer); time_enable = true; return IRQ_HANDLED; } @@ -76,13 +81,16 @@ static int capella_cm3602_enable(struct capella_cm3602_data *data) { int rc; D("%s\n", __func__); - time_enable = true; + //time_enable = true; if (data->enabled) { D("%s: already enabled\n", __func__); return 0; } - gpio_set_value(data->pdata->pwd_out_pin, SPI_GPIO_LOW); //CM3605_PWD output - gpio_set_value(data->pdata->ps_shutdown_pin, SPI_GPIO_LOW); //CM3605_PS_SHUTDOWN +/* gpio_direction_output(pdata->pwd_out_pin, SPI_GPIO_OUT); + gpio_set_value(pdata->pwd_out_pin, SPI_GPIO_LOW); //CM3605_PWD output + gpio_direction_output(pdata->ps_shutdown_pin, SPI_GPIO_OUT); + gpio_set_value(pdata->ps_shutdown_pin, SPI_GPIO_LOW); //CM3605_PS_SHUTDOWN +*/ data->pdata->power(1); data->enabled = !rc; if (!rc) @@ -99,8 +107,8 @@ static int capella_cm3602_disable(struct capella_cm3602_data *data) D("%s: already disabled\n", __func__); return 0; } - gpio_set_value(data->pdata->pwd_out_pin, GPIO_HIGH); //CM3605_PWD output - gpio_set_value(data->pdata->ps_shutdown_pin, GPIO_HIGH); //CM3605_PS_SHUTDOWN +// gpio_set_value(data->pdata->pwd_out_pin, GPIO_HIGH); //CM3605_PWD output +// gpio_set_value(data->pdata->ps_shutdown_pin, GPIO_HIGH); //CM3605_PS_SHUTDOWN data->pdata->power(0); data->enabled = 0; return rc; @@ -117,6 +125,7 @@ void cm3602_work_handler(struct work_struct *work) time_enable = false; input_report_abs(pdata->input_dev, ABS_DISTANCE, val); input_sync(pdata->input_dev); + printk("input_report_abs=%d\n",val); } } @@ -124,12 +133,12 @@ void cm3602_work_handler(struct work_struct *work) static void cm3602_timer(unsigned long data) { struct capella_cm3602_data *ip = data; - printk("------------------cm3602_timer,%d------------\n",time_enable); - + //printk("------------------cm3602_timer,%d------------\n",time_enable); + ip->cm3602_timer.expires = jiffies + HZ; + add_timer(&ip->cm3602_timer); if(time_enable) { - ip->cm3602_timer.expires = jiffies + HZ; - add_timer(&ip->cm3602_timer); + printk("------------------cm3602_timer,%d------------\n",time_enable); queue_work(ip->cm3602_workqueue, &ip->cm3602_work); } @@ -141,23 +150,8 @@ static int capella_cm3602_setup(struct capella_cm3602_data *ip) struct capella_cm3602_platform_data *pdata = ip->pdata; //int irq = gpio_to_irq(pdata->p_out); char b[20]; - - D("%s\n", __func__); -/* - rc = gpio_request(pdata->p_out, "gpio_proximity_out"); - if (rc < 0) { - pr_err("%s: gpio %d request failed (%d)\n", - __func__, pdata->p_out, rc); - goto done; - } - rc = gpio_direction_input(pdata->p_out); - if (rc < 0) { - pr_err("%s: failed to set gpio %d as input (%d)\n", - __func__, pdata->p_out, rc); - goto fail_free_p_out; - } -*/ + D("%s\n", __func__); rc = gpio_request(pdata->pwd_out_pin, "cm3602 out"); if (rc) { @@ -177,8 +171,8 @@ static int capella_cm3602_setup(struct capella_cm3602_data *ip) pr_err("%s: request gpio %d failed \n", __func__, pdata->irq_pin); return rc; } - rc = gpio_direction_input(pdata->irq_pin); - rc = request_irq(gpio_to_irq(pdata->irq_pin),capella_cm3602_irq_handler,SPI_GPIO_EDGE_FALLING,NULL, NULL); + //rc = gpio_direction_input(pdata->irq_pin); + rc = request_irq(gpio_to_irq(pdata->irq_pin),capella_cm3602_irq_handler,SPI_GPIO_EDGE_FALLING,NULL, ip); if (rc < 0) { pr_err("%s: request_irq failed for gpio %d (%d)\n", __func__, @@ -186,9 +180,6 @@ static int capella_cm3602_setup(struct capella_cm3602_data *ip) goto fail_free_p_out; } - //spi_gpio_set_pindirection(SPI_GPIO_P6_04, SPI_GPIO_IN); - //spi_gpio_get_pinlevel(SPI_GPIO_P6_04); - sprintf(b,"cm3602_workqueue"); ip->cm3602_workqueue = create_freezeable_workqueue(b); if(!ip->cm3602_workqueue) @@ -199,7 +190,7 @@ static int capella_cm3602_setup(struct capella_cm3602_data *ip) INIT_WORK(&ip->cm3602_work, cm3602_work_handler); setup_timer(&ip->cm3602_timer,cm3602_timer,(unsigned long)ip); ip->cm3602_timer.expires = jiffies + HZ; - //add_timer(&ip->cm3602_timer); + add_timer(&ip->cm3602_timer); /* rc = set_irq_wake(irq, 1); if (rc < 0) { @@ -278,7 +269,7 @@ static int capella_cm3602_probe(struct platform_device *pdev) struct capella_cm3602_platform_data *pdata; D("%s: probe\n", __func__); - printk("%s: probe]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n", __func__); + //printk("%s: probe]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n", __func__); pdata = pdev->dev.platform_data; if (!pdata) { pr_err("%s: missing pdata!\n", __func__); diff --git a/drivers/input/touchscreen/ctp_it7250.c b/drivers/input/touchscreen/ctp_it7250.c index 5d1094454427..8f78ca76d33d 100755 --- a/drivers/input/touchscreen/ctp_it7250.c +++ b/drivers/input/touchscreen/ctp_it7250.c @@ -37,6 +37,8 @@ struct Ctp_it7250_data { }; static struct i2c_client *Ctp_it7250_client; +#define Ctp_it7250_GPIO_INT RK2818_PIN_PE1 + #if 0 #define rk28printk(x...) printk(x) #else @@ -71,21 +73,21 @@ static struct KeyInfo panel_key_info[]={ static u8 gpucPointBuffer[14]; static u32 gpdwSampleX[3],gpdwSampleY[3],gpdwPressure[1]; -static int Ctp_it7250_rx_data( u8 reg,u8* rxData, int length) +static int Ctp_it7250_rx_data(struct i2c_client *client, u8 reg,u8* rxData, int length) { #if 0 int ret; struct i2c_adapter *adap;int i; struct i2c_msg msgs[2]; - if(!Ctp_it7250_client) + if(!client) return ret; - adap = Ctp_it7250_client->adapter; + adap = client->adapter; //·¢ËͼĴæÆ÷µØÖ· - msgs[0].addr = Ctp_it7250_client->addr; + msgs[0].addr = client->addr; msgs[0].buf = ® - msgs[0].flags = Ctp_it7250_client->flags; + msgs[0].flags = client->flags; msgs[0].len =1; msgs[0].scl_rate = 400*1000; //½ÓÊÕÊý¾Ý @@ -94,8 +96,8 @@ static int Ctp_it7250_rx_data( u8 reg,u8* rxData, int length) // rk28printk("msgs[0].buf = 0x%x rxData=0x%x\n",*(msgs[0].buf),*rxData); msgs[1].buf = rxData; - msgs[1].addr = Ctp_it7250_client->addr; - msgs[1].flags = Ctp_it7250_client->flags | I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].flags = client->flags | I2C_M_RD; msgs[1].len = length; msgs[1].scl_rate = 400*1000; @@ -109,18 +111,18 @@ static int Ctp_it7250_rx_data( u8 reg,u8* rxData, int length) #else //int i; -return i2c_master_reg8_recv(Ctp_it7250_client, reg, rxData, length, 400 * 1000); +return i2c_master_reg8_recv(client, reg, rxData, length, 400 * 1000); //for (i=0;iadapter; + struct i2c_adapter *adap = client->adapter; struct i2c_msg msg; u8 buf[128];//128 @@ -133,17 +135,17 @@ static int Ctp_it7250_tx_data(u8 reg,char *txData, int length) } rk28printk("\r\n"); // rk28printk("buf[0]=0x%x buf[1]=0x%x",buf[0],buf[1]); - msg.addr = Ctp_it7250_client->addr; + msg.addr = client->addr; //rk28printk("i2c addr=0x%x",msg.addr); msg.buf =&buf[0]; msg.len = length+1;//+1 means add the reg length;by roberts - msg.flags = Ctp_it7250_client->flags; + msg.flags = client->flags; msg.scl_rate = 400*1000; ret = i2c_transfer(adap, &msg, 1); return ret; #else - return i2c_master_reg8_send(Ctp_it7250_client, reg, txData, length, 400 * 1000); + return i2c_master_reg8_send(client, reg, txData, length, 400 * 1000); #endif @@ -153,35 +155,35 @@ return ret; -bool ReadQueryBuffer(u8* pucData) +bool ReadQueryBuffer(struct i2c_client *client, u8* pucData) { - return Ctp_it7250_rx_data( QUERY_BUFFER_INDEX, pucData, 1); + return Ctp_it7250_rx_data(client, QUERY_BUFFER_INDEX, pucData, 1); } -bool ReadCommandResponseBuffer(u8* pucData, unsigned int unDataLength) +bool ReadCommandResponseBuffer(struct i2c_client *client, u8* pucData, unsigned int unDataLength) { - return Ctp_it7250_rx_data( COMMAND_RESPONSE_BUFFER_INDEX, pucData, unDataLength); + return Ctp_it7250_rx_data(client, COMMAND_RESPONSE_BUFFER_INDEX, pucData, unDataLength); } -bool ReadPointBuffer(u8* pucData) +bool ReadPointBuffer(struct i2c_client *client, u8* pucData) { - return Ctp_it7250_rx_data( POINT_BUFFER_INDEX, pucData, 14); + return Ctp_it7250_rx_data(client, POINT_BUFFER_INDEX, pucData, 14); } -bool WriteCommandBuffer(u8* pucData, unsigned int unDataLength) +bool WriteCommandBuffer(struct i2c_client *client, u8* pucData, unsigned int unDataLength) { - return Ctp_it7250_tx_data(COMMAND_BUFFER_INDEX, pucData, unDataLength); + return Ctp_it7250_tx_data(client, COMMAND_BUFFER_INDEX, pucData, unDataLength); } static int Ctp_it7250_touch_open(struct input_dev *idev) { -struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(Ctp_it7250_client); +//struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client); //BTN_TOUCH =0 means no touch ;by robert - input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 0); - input_sync(Ctp_it7250->input_dev); + input_report_key(idev,BTN_TOUCH, 0); + input_sync(idev); return 0; } @@ -282,7 +284,7 @@ static int Ctp_it7250_init_irq(struct i2c_client *client) } ret = gpio_request(client->irq, "Ctp_it7250_int"); if (ret) { - rk28printk( "failed to request Ctp_it7250_init_irq GPIO%d\n",gpio_to_irq(client->irq)); + rk28printk( "failed to request Ctp_it7250_init_irq GPIO%d\n",client->irq); return ret; } #if 1 @@ -293,13 +295,10 @@ ret = gpio_direction_input(client->irq); } gpio_pull_updown(client->irq,GPIOPullUp); #endif - - rk28printk("%s gpio_to_irq(%d) is %d\n",__FUNCTION__,client->irq,gpio_to_irq(client->irq)); - client->irq = gpio_to_irq(client->irq); + Ctp_it7250->irq = gpio_to_irq(client->irq); #endif - ret = request_irq(client->irq, Ctp_it7250_touch_irq, IRQF_TRIGGER_LOW, client->dev.driver->name, Ctp_it7250); - Ctp_it7250->irq=client->irq; + ret = request_irq(Ctp_it7250->irq, Ctp_it7250_touch_irq, IRQF_TRIGGER_LOW, client->dev.driver->name, Ctp_it7250); rk28printk("%s request irq is %d,irq1 is %d,ret is 0x%x\n",__FUNCTION__,client->irq,Ctp_it7250->irq,ret); if (ret ) { rk28printk(KERN_ERR "Ctp_it7250_init_irq: request irq failed,ret is %d\n",ret); @@ -315,7 +314,7 @@ ret = gpio_direction_input(client->irq); // Input --- NULL //Output --- return true if the command execute successfully, otherwuse return false. // ================================================================================ -bool GetFirmwareInformation() +bool GetFirmwareInformation(struct i2c_client *client) { u8 ucWriteLength, ucReadLength; u8 pucData[128]; @@ -329,14 +328,14 @@ int i; // Query do { - if(!ReadQueryBuffer(&ucQuery)) + if(!ReadQueryBuffer(client, &ucQuery)) { ucQuery = QUERY_BUSY; } }while(ucQuery & QUERY_BUSY); // Write Command - if(!WriteCommandBuffer(pucData, ucWriteLength)) + if(!WriteCommandBuffer(client, pucData, ucWriteLength)) { return false; } @@ -344,7 +343,7 @@ int i; // Query do { - if(!ReadQueryBuffer(&ucQuery)) + if(!ReadQueryBuffer(client, &ucQuery)) { ucQuery = QUERY_BUSY; } @@ -354,7 +353,7 @@ int i; pucData[7] == 0 ; pucData[8] == 0; // Read Command Response - if(!ReadCommandResponseBuffer(pucData, ucReadLength)) + if(!ReadCommandResponseBuffer(client, pucData, ucReadLength)) { return false; } @@ -384,7 +383,7 @@ for (i =0;iclient; + int PE1status = 0; // rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__); - PE1status = gpio_get_value(Ctp_it7250->client->irq); + //PE1status = gpio_get_value(Ctp_it7250_GPIO_INT); + PE1status = gpio_get_value(client->irq); // PE1status ΪµÍ£¬±íʾµÍµçƽÖжÏÓÐЧ if (!PE1status) { // rk28printk("%s PE1status low!! \r\n",__FUNCTION__); - if(!ReadQueryBuffer(&ucQueryResponse)) + if(!ReadQueryBuffer(client, &ucQueryResponse)) {rk28printk("%s++++ %d ucQueryResponse=0x%x \r\n",__FUNCTION__,__LINE__,ucQueryResponse); return false; } @@ -817,7 +831,7 @@ static void Ctp_it7250_delaywork_func(struct work_struct *work) // Touch Event if(ucQueryResponse & QUERY_POINT) {//rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__); - if(!ReadPointBuffer(gpucPointBuffer)) + if(!ReadPointBuffer(client, gpucPointBuffer)) {rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__); return false; } @@ -825,8 +839,7 @@ static void Ctp_it7250_delaywork_func(struct work_struct *work) switch(gpucPointBuffer[0] & 0xF0) { case 0x00: - dwTouchEvent = CaptouchGetSampleValue(gpdwSampleX, gpdwSampleY, -gpdwPressure); + dwTouchEvent = CaptouchGetSampleValue(gpdwSampleX, gpdwSampleY, gpdwPressure); if(dwTouchEvent == 0) { //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_FINGER_RELEASE); @@ -841,7 +854,8 @@ gpdwPressure); input_report_abs(Ctp_it7250->input_dev, ABS_X, gpdwSampleX[0]);// & 0xfff input_report_abs(Ctp_it7250->input_dev, ABS_Y, gpdwSampleY[0]); //& 0xfff input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 1); - input_sync(Ctp_it7250->input_dev);rk28printk("x=%d y=%d \r\n",gpdwSampleX[0],gpdwSampleY[0]); + input_sync(Ctp_it7250->input_dev); + rk28printk("x=%d y=%d \r\n",gpdwSampleX[0],gpdwSampleY[0]); } else { @@ -910,10 +924,10 @@ gpdwPressure); } else if (ucQueryResponse & QUERY_ERROR) { - if (!CaptouchReset()) + if (!CaptouchReset(client)) rk28printk("!! CaptouchReset success \r\n"); mdelay(100); - //if (!CaptouchMode(0x00)) + //if (!CaptouchMode(client, 0x00)) //rk28printk("!! CaptouchMode success \r\n"); } } @@ -948,7 +962,9 @@ gpdwPressure); i2c_set_clientdata(client, Ctp_it7250); - +if (!CaptouchHWInitial(client)) + goto err_free_mem; +Ctp_it7250_init_irq(client); ts_input_init(client); // CTS_configure_pin(client); @@ -964,8 +980,7 @@ mdelay(5); #endif } -CaptouchHWInitial(); -Ctp_it7250_init_irq(client); + //²»ÊDzéѯģʽ£¬²»ÐèÒªÂÖѯ @@ -974,6 +989,9 @@ Ctp_it7250_init_irq(client); rk28printk("+++++++ %s+++++++\n", __FUNCTION__); return 0; +err_free_mem: + kfree(Ctp_it7250); + return false; } @@ -1006,7 +1024,7 @@ struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdat // Query do { - if(!ReadQueryBuffer(&ucQuery)) + if(!ReadQueryBuffer(client, &ucQuery)) { ucQuery = QUERY_BUSY; } @@ -1014,7 +1032,7 @@ struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdat // Write Command rk28printk("%s WriteCommandBuffer\r\n",__FUNCTION__); - if(!WriteCommandBuffer(pucData, ucWriteLength)) + if(!WriteCommandBuffer(client, pucData, ucWriteLength)) { return false; } @@ -1032,7 +1050,7 @@ struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdat //read command to wakeup ctp #if 1 u8 ucQuery; -ReadQueryBuffer(&ucQuery); +ReadQueryBuffer(client, &ucQuery); #endif //wakeup end enable_irq(Ctp_it7250->irq); diff --git a/drivers/input/touchscreen/xpt2046_ts_320X480.c b/drivers/input/touchscreen/xpt2046_ts_320X480.c index 18992368edd8..20079368df05 100755 --- a/drivers/input/touchscreen/xpt2046_ts_320X480.c +++ b/drivers/input/touchscreen/xpt2046_ts_320X480.c @@ -1010,7 +1010,7 @@ static int __init xpt2046_init(void) { return spi_register_driver(&xpt2046_driver); } -module_init(xpt2046_init); +late_initcall_sync(xpt2046_init); static void __exit xpt2046_exit(void) { diff --git a/drivers/regulator/rk2818_lp8725.c b/drivers/regulator/rk2818_lp8725.c index ba29580aa38e..807d8bc8731d 100644 --- a/drivers/regulator/rk2818_lp8725.c +++ b/drivers/regulator/rk2818_lp8725.c @@ -31,6 +31,15 @@ REVISION 0.01 #include #include #include +#include +#include + +//add by robert for reboot notifier +#include +#include + +//end add + #if 0 @@ -670,6 +679,90 @@ static int lp8725_set_bits(struct lp8725 *lp8725, u8 reg, u16 mask, u16 val) } +//add by robert for power on bp +#define AP_TD_UNDEFINED_GBIN5 FPGA_PIO2_02 +#define AP_RESET_TD FPGA_PIO2_04 +#define AP_SHUTDOWN_TD_PMU FPGA_PIO2_05 +#define AP_PW_EN_TD FPGA_PIO2_03 + +static int bp_power_on(void) +{ + int ret=0; + + ret = gpio_request(AP_TD_UNDEFINED_GBIN5, NULL); + if (ret) { + printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__); + goto err; + } + ret = gpio_request(AP_RESET_TD, NULL); + if (ret) { + printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__); + goto err0; + } + + + ret = gpio_request(AP_SHUTDOWN_TD_PMU, NULL); + if (ret) { + printk("%s:failed to request fpga %d\n",__FUNCTION__,__LINE__); + goto err1; + } + + ret = gpio_request(AP_PW_EN_TD, NULL); + if (ret) { + printk("%s:failed to request fpga %d\n",__FUNCTION__,__LINE__); + goto err2; + } + + gpio_set_value(AP_TD_UNDEFINED_GBIN5, 1); + gpio_direction_output(AP_TD_UNDEFINED_GBIN5, 1); + gpio_direction_input(AP_RESET_TD); + + gpio_set_value(AP_SHUTDOWN_TD_PMU, 0); + gpio_direction_output(AP_SHUTDOWN_TD_PMU, 0); + + gpio_set_value(AP_PW_EN_TD, 0); + gpio_direction_output(AP_PW_EN_TD, 0); + mdelay(1); + gpio_set_value(AP_PW_EN_TD, 1); + mdelay(1200); + gpio_set_value(AP_PW_EN_TD, 0); + + return true; +err2: + gpio_free(AP_SHUTDOWN_TD_PMU); +err1: + gpio_free(AP_RESET_TD); +err0: + gpio_free(AP_TD_UNDEFINED_GBIN5); +err: + return false; +} + + + +static int bp_power_off(struct notifier_block *this, + unsigned long code, void *unused) +{ + printk("+++--++++++%s_________%d \r\n",__FUNCTION__,code); + + gpio_set_value(AP_TD_UNDEFINED_GBIN5, 0); + + gpio_set_value(AP_PW_EN_TD, 0); + //gpio_direction_output(AP_PW_EN_TD, 0); + mdelay(1); + gpio_set_value(AP_PW_EN_TD, 1); + mdelay(1200); + gpio_set_value(AP_PW_EN_TD, 0); + + mdelay(5000); + gpio_set_value(AP_SHUTDOWN_TD_PMU, 1); + mdelay(1200); + // gpio_free(AP_PW_EN_TD); +printk("++++--+++++%s ok_________\r\n",__FUNCTION__); + return NOTIFY_DONE; +} +//add end + static int lp8725_set_init(void) { int tmp = 0; @@ -749,6 +842,11 @@ static int lp8725_set_init(void) tmp = regulator_get_voltage(buck2); DBG_INFO("***regulator_set_init: buck2 vcc =%d\n",tmp); + +//add by robert for power on bp + bp_power_on(); +//end add + return(0); } @@ -822,6 +920,7 @@ static int __devexit lp8725_i2c_remove(struct i2c_client *i2c) { struct lp8725 *lp8725 = i2c_get_clientdata(i2c); int i; + for (i = 0; i < lp8725->num_regulators; i++) if (lp8725->rdev[i]) regulator_unregister(lp8725->rdev[i]); @@ -849,6 +948,15 @@ static struct i2c_driver lp8725_i2c_driver = { .id_table = lp8725_i2c_id, }; + +//add by robert for bp powerdown register +static struct notifier_block BP_powerdown_notifier = { + .notifier_call = bp_power_off, +}; +//end add + + + static int __init lp8725_module_init(void) { int ret; @@ -857,12 +965,25 @@ static int __init lp8725_module_init(void) if (ret != 0) pr_err("Failed to register I2C driver: %d\n", ret); + //add by robert for bp powerdown register + ret = register_reboot_notifier(&BP_powerdown_notifier); + if (ret != 0) + { + printk("cannot register reboot notifier (err=%d), %s\n", ret,__FUNCTION__); + } + //end add + + return ret; } module_init(lp8725_module_init); static void __exit lp8725_module_exit(void) { +//add by robert for bp power down + unregister_reboot_notifier(&BP_powerdown_notifier); +//end add + i2c_del_driver(&lp8725_i2c_driver); } module_exit(lp8725_module_exit); diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c old mode 100644 new mode 100755 index 7232a538d399..e1ca7f1b4021 --- a/drivers/rtc/alarm.c +++ b/drivers/rtc/alarm.c @@ -234,6 +234,23 @@ int alarm_cancel(struct alarm *alarm) cpu_relax(); } } +int rtc_change_time(struct timespec new_time) +{ + int i; + int ret; + unsigned long flags; + struct rtc_time rtc_new_rtc_time; + struct timespec tmp_time; + + rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); + + printk("set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", + new_time.tv_sec, new_time.tv_nsec, + rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, + rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, + rtc_new_rtc_time.tm_mday, + rtc_new_rtc_time.tm_year + 1900); +} /** * alarm_set_rtc - set the kernel and rtc walltime @@ -249,7 +266,7 @@ int alarm_set_rtc(struct timespec new_time) rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); - pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", + printk("set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", new_time.tv_sec, new_time.tv_nsec, rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, @@ -320,20 +337,20 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) struct alarm *alarm; unsigned long flags; ktime_t now; - + printk("alarm_timer_triggered\n"); spin_lock_irqsave(&alarm_slock, flags); base = container_of(timer, struct alarm_queue, timer); now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); now = ktime_sub(now, base->delta); - pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", + printk( "alarm_timer_triggered type %d at %lld\n", base - alarms, ktime_to_ns(now)); while (base->first) { alarm = container_of(base->first, struct alarm, node); if (alarm->softexpires.tv64 > now.tv64) { - pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", + printk( "don't call alarm, %pF, %lld (s %lld)\n", alarm->function, ktime_to_ns(alarm->expires), ktime_to_ns(alarm->softexpires)); break; @@ -341,7 +358,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) base->first = rb_next(&alarm->node); rb_erase(&alarm->node, &base->alarms); RB_CLEAR_NODE(&alarm->node); - pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", + printk("call alarm, type %d, func %pF, %lld (s %lld)\n", alarm->type, alarm->function, ktime_to_ns(alarm->expires), ktime_to_ns(alarm->softexpires)); @@ -350,9 +367,10 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) spin_lock_irqsave(&alarm_slock, flags); } if (!base->first) - pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); + printk( "no more alarms of type %d\n", base - alarms); update_timer_locked(base, true); spin_unlock_irqrestore(&alarm_slock, flags); + printk("---alarm_timer_triggered---\n"); return HRTIMER_NORESTART; } @@ -378,7 +396,7 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) struct alarm_queue *wakeup_queue = NULL; struct alarm_queue *tmp_queue = NULL; - pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); + printk( "alarm_suspend(%p, %d)\n", pdev, state.event); spin_lock_irqsave(&alarm_slock, flags); suspended = true; @@ -409,10 +427,11 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); rtc_alarm.enabled = 1; + //rtc_alarm.time.tm_min +=4; rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - pr_alarm(SUSPEND, + printk( "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", rtc_alarm_time, rtc_current_time, rtc_delta.tv_sec, rtc_delta.tv_nsec); @@ -433,15 +452,87 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) spin_unlock_irqrestore(&alarm_slock, flags); } } + printk( "alarm_suspend over\n"); return err; } +static int alarm_shutdown(struct platform_device *pdev, pm_message_t state) +{ + int err = 0; + unsigned long flags; + struct rtc_wkalrm rtc_alarm; + struct rtc_time rtc_current_rtc_time; + unsigned long rtc_current_time; + unsigned long rtc_alarm_time; + struct timespec rtc_current_timespec; + struct timespec rtc_delta; + struct alarm_queue *wakeup_queue = NULL; + struct alarm_queue *tmp_queue = NULL; + + printk( "alarm_suspend(%p, %d)\n", pdev, state.event); + + spin_lock_irqsave(&alarm_slock, flags); + suspended = true; + spin_unlock_irqrestore(&alarm_slock, flags); + + hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); + hrtimer_cancel(&alarms[ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK].timer); + + tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; + if (tmp_queue->first) + wakeup_queue = tmp_queue; + tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; + if (tmp_queue->first && (!wakeup_queue || + hrtimer_get_expires(&tmp_queue->timer).tv64 < + hrtimer_get_expires(&wakeup_queue->timer).tv64)) + wakeup_queue = tmp_queue; + if (wakeup_queue) { + rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); + rtc_current_timespec.tv_nsec = 0; + rtc_tm_to_time(&rtc_current_rtc_time, + &rtc_current_timespec.tv_sec); + save_time_delta(&rtc_delta, &rtc_current_timespec); + + rtc_alarm_time = timespec_sub(ktime_to_timespec( + hrtimer_get_expires(&wakeup_queue->timer)), + rtc_delta).tv_sec; + + rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); + rtc_alarm.enabled = 1; + rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); + rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); + rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); + printk( + "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", + rtc_alarm_time, rtc_current_time, + rtc_delta.tv_sec, rtc_delta.tv_nsec); + if (rtc_current_time + 1 >= rtc_alarm_time) { + pr_alarm(SUSPEND, "alarm about to go off\n"); + memset(&rtc_alarm, 0, sizeof(rtc_alarm)); + rtc_alarm.enabled = 0; + rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); + + spin_lock_irqsave(&alarm_slock, flags); + suspended = false; + wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); + update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], + false); + update_timer_locked(&alarms[ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); + err = -EBUSY; + spin_unlock_irqrestore(&alarm_slock, flags); + } + } + printk( "alarm_suspend over\n"); + return err; +} static int alarm_resume(struct platform_device *pdev) { struct rtc_wkalrm alarm; unsigned long flags; - pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); + printk( "alarm_resume(%p)\n", pdev); memset(&alarm, 0, sizeof(alarm)); alarm.enabled = 0; @@ -516,6 +607,7 @@ static struct class_interface rtc_alarm_interface = { static struct platform_driver alarm_driver = { .suspend = alarm_suspend, .resume = alarm_resume, + .shutdown = alarm_shutdown, .driver = { .name = "alarm" } @@ -525,7 +617,7 @@ static int __init alarm_late_init(void) { unsigned long flags; struct timespec tmp_time, system_time; - + printk("alarm_late_init\n"); /* this needs to run after the rtc is read at boot */ spin_lock_irqsave(&alarm_slock, flags); /* We read the current rtc and system time so we can later calulate @@ -539,6 +631,7 @@ static int __init alarm_late_init(void) timespec_to_ktime(timespec_sub(tmp_time, system_time)); spin_unlock_irqrestore(&alarm_slock, flags); + printk("---alarm_late_init----\n"); return 0; } @@ -546,7 +639,7 @@ static int __init alarm_driver_init(void) { int err; int i; - + printk("alarm_driver_init\n"); for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { hrtimer_init(&alarms[i].timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); @@ -563,7 +656,7 @@ static int __init alarm_driver_init(void) err = class_interface_register(&rtc_alarm_interface); if (err < 0) goto err2; - + printk("---alarm_driver_init---\n"); return 0; err2: diff --git a/drivers/rtc/rtc-s35392a.c b/drivers/rtc/rtc-s35392a.c index ff1dbe809fe6..05ceb9d8b556 100755 --- a/drivers/rtc/rtc-s35392a.c +++ b/drivers/rtc/rtc-s35392a.c @@ -19,24 +19,34 @@ #include #include #include +#include #include "rtc-s35392a.h" - +#define RTC_S35392A_INT RK2818_PIN_PE2 // #define RTC_RATE 100 * 1000 -#define S35392_TEST 1 +#define S35392_TEST 0 + +#if 1 +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif struct s35392a { struct i2c_client *client; struct rtc_device *rtc; int twentyfourhour; + struct work_struct work; }; + + static int s35392a_set_reg(struct s35392a *s35392a, const char reg, char *buf, int len) { struct i2c_client *client = s35392a->client; struct i2c_msg msg; int ret; - + int i; char *buff = buf; msg.addr = client->addr | reg; msg.flags = client->flags; @@ -45,6 +55,8 @@ static int s35392a_set_reg(struct s35392a *s35392a, const char reg, char *buf, i msg.scl_rate = RTC_RATE; ret = i2c_transfer(client->adapter,&msg,1); + for(i=0;itwentyfourhour) + { + if(hour<12) + return 0x80 | bin2bcd(hour) ; + else + return 0xc0| bin2bcd(hour) ; + } + else + { + if(hour<12) + return 0x80 | bin2bcd(hour) ; + else + return 0xc0 | bin2bcd(hour - 12); + } + +} + static int s35392a_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct s35392a *s35392a = i2c_get_clientdata(client); int i, err; char buf[7]; - printk("%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " + DBG("%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); @@ -215,9 +218,12 @@ static int s35392a_set_datetime(struct i2c_client *client, struct rtc_time *tm) buf[S35392A_BYTE_SECS] = bin2bcd(tm->tm_sec); /* This chip expects the bits of each byte to be in reverse order */ + for(i=0;i<7;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); for (i = 0; i < 7; ++i) buf[i] = bitrev8(buf[i]); - + for(i=0;i<7;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); err = s35392a_set_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf)); return err; @@ -232,11 +238,13 @@ static int s35392a_get_datetime(struct i2c_client *client, struct rtc_time *tm) err = s35392a_get_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf)); if (err < 0) return err; - + for(i=0;i<7;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); /* This chip returns the bits of each byte in reverse order */ for (i = 0; i < 7; ++i) buf[i] = bitrev8(buf[i]); - + for(i=0;i<7;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); tm->tm_sec = bcd2bin(buf[S35392A_BYTE_SECS]); tm->tm_min = bcd2bin(buf[S35392A_BYTE_MINS]); tm->tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_BYTE_HOURS]); @@ -246,22 +254,352 @@ static int s35392a_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_year = bcd2bin(buf[S35392A_BYTE_YEAR]) + 100; //tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); - printk( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); return rtc_valid_tm(tm); } -static int s35392a_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm const *tm) +static int s35392a_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *tm) { - struct s35392a *s35392a = i2c_get_clientdata(client); + struct s35392a *s35392a = i2c_get_clientdata(client); + char buf[3]; + int i,err; + char data; + DBG("%s:%d\n",__FUNCTION__,__LINE__); + err = s35392a_get_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf)); + if(err < 0) + return err; + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + for(i = 0;i < 3;++i) + buf[i] = bitrev8(buf[i]); + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + tm->time.tm_wday = -1; + tm->time.tm_hour = -1; + tm->time.tm_min = -1; + + if(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_ENABLE ) + tm->time.tm_wday = bcd2bin(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_DISABLE) ; + if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE) + tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]); + + if(buf[S35392A_ALARM_MINS] & S35392A_ALARM_ENABLE) + tm->time.tm_min = bcd2bin(buf[S35392A_ALARM_MINS] & S35392A_ALARM_DISABLE) ; + + + tm->time.tm_year = -1; + tm->time.tm_mon = -1; + tm->time.tm_mday = -1; + tm->time.tm_yday = -1; + tm->time.tm_sec = -1; + + DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec, + tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year, + tm->time.tm_wday); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + tm->enabled = ((data & S35392A_MASK_INT2) == S35392A_INT2_ENABLE); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + tm->pending = !!(data & S35392A_FLAG_INT2); + + DBG("%s:%d\n",__FUNCTION__,__LINE__); + return data; } -static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm const *tm) + +static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *tm) { - struct s35392a *s35392a = i2c_get_clientdata(client); + struct s35392a *s35392a = i2c_get_clientdata(client); + char buf[3]; + char data; + int i,err; + DBG("%s:%d\n",__FUNCTION__,__LINE__); + DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec, + tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year, + tm->time.tm_wday); + + buf[S35392A_ALARM_WDAYS] = tm->time.tm_wday>= 0 ? + (bin2bcd(tm->time.tm_wday) |S35392A_ALARM_ENABLE) : 0; + buf[S35392A_ALARM_WDAYS]=0; + buf[S35392A_ALARM_HOURS] = tm->time.tm_hour >=0 ? + s35392a_hour2reg(s35392a, tm->time.tm_hour) : 0; + buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0? + bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0; + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + for(i = 0;i < 3;++i) + buf[i] = bitrev8(buf[i]); + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + if(tm->enabled) + { + data = 0x00; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1); + + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + //data = (data |S35392A_FLAG_INT2AE) & 0x2; + data = 0x02; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + printk("data = 0x%x\n",data); + err = s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf)); + return err; + } + else + { + //s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + //data &= ~S35392A_FLAG_INT1AE; + //s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); + } + return -1; + +} +static int s35392a_i2c_read_alarm0(struct i2c_client *client, struct rtc_wkalrm *tm) +{ + struct s35392a *s35392a = i2c_get_clientdata(client); + char buf[3]; + int i,err; + char data; + DBG("%s:%d\n",__FUNCTION__,__LINE__); + err = s35392a_get_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf)); + if(err < 0) + return err; + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + for(i = 0;i < 3;++i) + buf[i] = bitrev8(buf[i]); + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + tm->time.tm_wday = -1; + tm->time.tm_hour = -1; + tm->time.tm_min = -1; + + if(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_ENABLE ) + tm->time.tm_wday = bcd2bin(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_DISABLE) ; + + if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE) + tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]); + + if(buf[S35392A_ALARM_MINS] & S35392A_ALARM_ENABLE) + tm->time.tm_min = bcd2bin(buf[S35392A_ALARM_MINS] & S35392A_ALARM_DISABLE) ; + + + tm->time.tm_year = -1; + tm->time.tm_mon = -1; + tm->time.tm_mday = -1; + tm->time.tm_yday = -1; + tm->time.tm_sec = -1; + + DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec, + tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year, + tm->time.tm_wday); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + tm->enabled = ((data & S35392A_MASK_INT1) == S35392A_INT1_ENABLE); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + tm->pending = !!(data & S35392A_FLAG_INT1); + + DBG("%s:%d\n",__FUNCTION__,__LINE__); + return data; +} + +static int s35392a_i2c_set_alarm0(struct i2c_client *client, struct rtc_wkalrm *tm) +{ + struct s35392a *s35392a = i2c_get_clientdata(client); + char buf[3]; + char data; + int i,err; + DBG("%s:%d\n",__FUNCTION__,__LINE__); + DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec, + tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year, + tm->time.tm_wday); + + //buf[S35392A_ALARM_WDAYS] = tm->time.tm_wday>= 0 ? + // (bin2bcd(tm->time.tm_wday) |S35392A_ALARM_ENABLE) : 0; + buf[S35392A_ALARM_WDAYS]=0; + buf[S35392A_ALARM_HOURS] = tm->time.tm_hour >=0 ? + s35392a_hour2reg(s35392a, tm->time.tm_hour) : 0; + buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0? + bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0; + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + for(i = 0;i < 3;++i) + buf[i] = bitrev8(buf[i]); + for(i=0;i<3;i++) + printk("buf[%d]=0x%x\n",i,buf[i]); + if(tm->enabled) + { + data = 0x00; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1); + + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + //ta = (data |S35392A_FLAG_INT1AE) & 0x20; + data = 0x02; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + printk("data = 0x%x\n",data); + err = s35392a_set_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf)); + return err; + } + else + { + //s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + //data &= ~S35392A_FLAG_INT1AE; + //s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); + } + return -1; + +} +static void s35392a_alarm_test(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time) +{ + struct rtc_wkalrm rtc_alarm,tm; + char data; + struct s35392a *s35392a = i2c_get_clientdata(client); + DBG("%s:%d\n",__FUNCTION__,__LINE__); + + rtc_alarm.time.tm_sec = rtc_alarm_rtc_time.tm_sec; + rtc_alarm.time.tm_min = (rtc_alarm_rtc_time.tm_min + 1) % 60; + if((rtc_alarm.time.tm_min + 2)/60 > 0) + rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour+1; + else + rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour; + if(rtc_alarm.time.tm_hour >24) + rtc_alarm.time.tm_hour =24; + rtc_alarm.time.tm_mday = rtc_alarm_rtc_time.tm_mday; + rtc_alarm.time.tm_mon = rtc_alarm_rtc_time.tm_mon; + rtc_alarm.time.tm_year = rtc_alarm_rtc_time.tm_year; + rtc_alarm.time.tm_wday = rtc_alarm_rtc_time.tm_wday; + rtc_alarm.time.tm_yday = rtc_alarm_rtc_time.tm_yday; + rtc_alarm.enabled = 1; + DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n", + rtc_alarm.time.tm_hour, rtc_alarm.time.tm_min, + rtc_alarm.time.tm_sec, rtc_alarm.time.tm_mon + 1, + rtc_alarm.time.tm_mday, rtc_alarm.time.tm_year + 1900,rtc_alarm.time.tm_wday); + s35392a_i2c_set_alarm(client,&rtc_alarm); + data = s35392a_i2c_read_alarm(client,&tm); + DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n", + tm.time.tm_hour, tm.time.tm_min, + tm.time.tm_sec, tm.time.tm_mon + 1, + tm.time.tm_mday, tm.time.tm_year + 1900,tm.time.tm_wday); + + DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT2); + do + { + msleep(10000); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + DBG("-----------------------------------------------0x%0x\n",data); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + DBG("-----------------------------------------------0x%0x\n",data); + }while((data & S35392A_FLAG_INT2) == 0); + + msleep(20000); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + DBG("--------------------last-------------------------0x%0x\n",data); + data=0x00; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); +} + +static void s35392a_alarm_test0(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time) +{ + struct rtc_wkalrm rtc_alarm,tm; + char data; + struct s35392a *s35392a = i2c_get_clientdata(client); + DBG("%s:%d\n",__FUNCTION__,__LINE__); + + rtc_alarm.time.tm_sec = rtc_alarm_rtc_time.tm_sec; + rtc_alarm.time.tm_min = (rtc_alarm_rtc_time.tm_min + 3) % 60; + if((rtc_alarm.time.tm_min + 3)/60 > 0) + rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour+1; + else + rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour; + if(rtc_alarm.time.tm_hour >24) + rtc_alarm.time.tm_hour =24; + rtc_alarm.time.tm_mday = rtc_alarm_rtc_time.tm_mday; + rtc_alarm.time.tm_mon = rtc_alarm_rtc_time.tm_mon; + rtc_alarm.time.tm_year = rtc_alarm_rtc_time.tm_year; + rtc_alarm.time.tm_wday = rtc_alarm_rtc_time.tm_wday; + rtc_alarm.time.tm_yday = rtc_alarm_rtc_time.tm_yday; + rtc_alarm.enabled = 1; + DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n", + rtc_alarm.time.tm_hour, rtc_alarm.time.tm_min, + rtc_alarm.time.tm_sec, rtc_alarm.time.tm_mon + 1, + rtc_alarm.time.tm_mday, rtc_alarm.time.tm_year + 1900,rtc_alarm.time.tm_wday); + s35392a_i2c_set_alarm0(client,&rtc_alarm); + data = s35392a_i2c_read_alarm0(client,&tm); + DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n", + tm.time.tm_hour, tm.time.tm_min, + tm.time.tm_sec, tm.time.tm_mon + 1, + tm.time.tm_mday, tm.time.tm_year + 1900,tm.time.tm_wday); + + DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT1); + do + { + msleep(10000); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + DBG("-----------------------------------------------0x%0x\n",data); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + DBG("-----------------------------------------------0x%0x\n",data); + + }while((data & S35392A_FLAG_INT1) == 0); + msleep(10000); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + DBG("--------------------last-------------------------0x%0x\n",data); + data=0x00; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1); + +} + +static int s35392a_set_init_time(struct s35392a *s35392a) +{ + struct rtc_time *tm; + struct i2c_client *client = s35392a->client; + tm->tm_year = 110; + tm->tm_mon = 8; + tm->tm_mday = 8; + tm->tm_wday = 0; + tm->tm_hour = 8; + tm->tm_min = 8; + tm->tm_sec = 8; + s35392a_set_datetime(client, tm); + return 0; +} +static int s35392a_reset(struct s35392a *s35392a) +{ + char buf[1]; + if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf)) < 0) + return -EIO; + if (!(buf[0] & (S35392A_FLAG_POC | S35392A_FLAG_BLD))) + return 0; + + buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H); + buf[0] &= 0xf0; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf)); + //s35392a_set_init_time( s35392a); + return 0; +} + +static int s35392a_disable_test_mode(struct s35392a *s35392a) +{ + char buf[1]; + + if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf)) < 0) + return -EIO; + + if (!(buf[0] & S35392A_FLAG_TEST)) + return 0; + + buf[0] &= ~S35392A_FLAG_TEST; + return s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf)); } static int s35392a_rtc_read_time(struct device *dev, struct rtc_time *tm) { @@ -285,29 +623,29 @@ static int s35392a_i2c_open_alarm(struct i2c_client *client ) { u8 data; struct s35392a *s35392a = i2c_get_clientdata(client); - + DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); s35392a_get_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); - data = (data |S35392A_FLAG_INT1AE) & 0x3F; + data = (data |S35392A_FLAG_INT2AE) & 0x02; s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); - + DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); return 0; } static int s35392a_i2c_close_alarm(struct i2c_client *client ) { u8 data; struct s35392a *s35392a = i2c_get_clientdata(client); - + DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); s35392a_get_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); - data &= ~S35392A_FLAG_INT1AE; + data &= ~S35392A_FLAG_INT2AE; s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1); - + DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); return 0; } static int s35392a_rtc_ioctl(struct device *dev,unsigned int cmd,unsigned long arg) { struct i2c_client *client = to_i2c_client(dev); - + DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); switch(cmd) { case RTC_AIE_OFF: @@ -325,7 +663,7 @@ static int s35392a_rtc_ioctl(struct device *dev,unsigned int cmd,unsigned long a err: return -EIO; } -static int s35392_rtc_proc(struct device *dev, unsigned int cmd, unsigned long arg) +static int s35392a_rtc_proc(struct device *dev, unsigned int cmd, unsigned long arg) { return 0; } @@ -336,11 +674,91 @@ static const struct rtc_class_ops s35392a_rtc_ops = { .read_alarm = s35392a_rtc_read_alarm, .set_alarm = s35392a_rtc_set_alarm, .ioctl = s35392a_rtc_ioctl, - .proc = s35392_rtc_proc + .proc = s35392a_rtc_proc +}; + + + +#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) +static ssize_t s35392a_sysfs_show_flags(struct device *dev, + struct device_attribute *attr, char *buf) +{ + DBG("\n@@@@@@@@@@@s35392a_sysfs_show_flags@@@@@@@@@@@@@\n"); + + return -EIO; + +} +static DEVICE_ATTR(flags, S_IRUGO, s35392a_sysfs_show_flags, NULL); + +static ssize_t s35392a_sysfs_show_sqwfreq(struct device *dev, + struct device_attribute *attr, char *buf) +{ + DBG("\n@@@@@@@@@@@ s35392a_sysfs_show_sqwfreq@@@@@@@@@@@@@\n"); + struct i2c_client *client = to_i2c_client(dev); + return 0; +} +static ssize_t s35392a_sysfs_set_sqwfreq(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + DBG("\n@@@@@@@@@@@s35392a_sysfs_set_sqwfreq@@@@@@@@@@@@@\n"); + + return count; +} +static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR, + s35392a_sysfs_show_sqwfreq, s35392a_sysfs_set_sqwfreq); + +static struct attribute *attrs[] = { + &dev_attr_flags.attr, + &dev_attr_sqwfreq.attr, + NULL, +}; +static struct attribute_group attr_group = { + .attrs = attrs, }; +static int s35392a_sysfs_register(struct device *dev) +{ + DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n"); + return sysfs_create_group(&dev->kobj, &attr_group); + +} +#else +static int s35392a_sysfs_register(struct device *dev) +{ + DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n"); + return 0; + +} +#endif static struct i2c_driver s35392a_driver; +static void s35392a_work_func(struct work_struct *work) +{ + struct s35392a *s35392a = container_of(work, struct s35392a, work); + struct i2c_client *client = s35392a->client; + + printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n"); + + char data = 0x00; + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + data = 0x00; + s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1); + + printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n"); + + enable_irq(client->irq); +} + +static void s35392a_wakeup_irq(int irq, void *dev_id) +{ + struct s35392a *s35392a = (struct s35392a *)dev_id; + + disable_irq_nosync(irq); + schedule_work(&s35392a->work); +} + static int s35392a_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -349,6 +767,7 @@ static int s35392a_probe(struct i2c_client *client, struct s35392a *s35392a; struct rtc_time tm; char buf[1]; + printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { err = -ENODEV; @@ -389,14 +808,48 @@ static int s35392a_probe(struct i2c_client *client, if (s35392a_get_datetime(client, &tm) < 0) dev_warn(&client->dev, "clock needs to be set\n"); - + s35392a->rtc = rtc_device_register(s35392a_driver.driver.name, &client->dev, &s35392a_rtc_ops, THIS_MODULE); - + if (IS_ERR(s35392a->rtc)) { err = PTR_ERR(s35392a->rtc); goto exit_dummy; } + err = s35392a_sysfs_register(&client->dev); + if(err) + { + dev_err(&client->dev, "error sysfs register\n"); + goto exit_dummy; + } + + if(err = gpio_request(RTC_S35392A_INT, "rtc gpio")) + { + dev_err(&client->dev, "gpio request fail\n"); + gpio_free(RTC_S35392A_INT); + goto exit_dummy; + } + + gpio_pull_updown(RTC_S35392A_INT,GPIOPullDown); + + if(err = request_irq(gpio_to_irq(RTC_S35392A_INT),s35392a_wakeup_irq,IRQF_TRIGGER_HIGH,NULL,s35392a) <0) + { + printk("unable to request rtc irq\n"); + goto exit_dummy; + } + + INIT_WORK(&s35392a->work, s35392a_work_func); + +#if 0 //S35392_TEST + //i=2; + while(1) + { + s35392a_get_datetime(client, &tm); + s35392a_alarm_test(client, tm); + //sleep(200); + } +#endif + printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__); return 0; diff --git a/drivers/rtc/rtc-s35392a.h b/drivers/rtc/rtc-s35392a.h index 079df16313d9..4d57e1cc7ea7 100755 --- a/drivers/rtc/rtc-s35392a.h +++ b/drivers/rtc/rtc-s35392a.h @@ -31,17 +31,27 @@ #define S35392A_BYTE_MINS 5 #define S35392A_BYTE_SECS 6 +#define S35392A_ALARM_WDAYS 0 +#define S35392A_ALARM_HOURS 1 +#define S35392A_ALARM_MINS 2 + #define S35392A_FLAG_POC 0x01 #define S35392A_FLAG_BLD 0x02 -#define S35392A_FLAG_INT2 0x04 -#define S35392A_FLAG_INT1 0x08 +#define S35392A_FLAG_INT2 0x04 +#define S35392A_FLAG_INT1 0x08 #define S35392A_FLAG_24H 0x40 #define S35392A_FLAG_TEST 0x01 #define S35392A_FLAG_INT1AE 0x20 #define S35392A_FLAG_RESET 0x80 +#define S35392A_FLAG_INT2AE 0x2 - +#define S35392A_ALARM_ENABLE 0X80 +#define S35392A_ALARM_DISABLE 0X7F +#define S35392A_MASK_INT1 0XE0 +#define S35392A_INT1_ENABLE 0X20 +#define S35392A_MASK_INT2 0X0E +#define S35392A_INT2_ENABLE 0X02 //#define S35392_STATUS_INT1 (~(0x3<<5)) //#define S35392_STATUS_INT2 (~(0x3<<1)) -- 2.34.1