Пример #1
0
static int 
ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, int count)
{	
#if defined (CONFIG_MODEM_IFX)
	unsigned int u32register = 0 ;
	unsigned int value  = 0;
#endif
	struct ifx_spi_data *spi_data = (struct ifx_spi_data *)tty->driver_data;

	if(spi_data==NULL)
	{
		printk("ifx_spi_write failed : spi_data is null\n");	//syblue.lee 100604
		return 0;
	}

        ifx_ret_count = 0;
#if defined (CONFIG_MODEM_MDM)
	DUMP_SPI_BUFFER(__FUNCTION__, buf, count);
#endif	
	spi_data->ifx_tty = tty;
	spi_data->ifx_tty->low_latency = 1;
	if( !buf ){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Buffer NULL\n");
		return ifx_ret_count;
	}
	if(!count){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Count is ZERO\n");
		return ifx_ret_count;
	}
	ifx_master_initiated_transfer = 1;
	ifx_spi_buf = buf;
	ifx_spi_count = count;
	SPI_DEBUG_PRINT("ifx_spi_write\n");	
	ifx_spi_set_mrdy_signal(1);  
#if defined (CONFIG_MODEM_MDM)
	wait_for_completion(&spi_data->ifx_read_write_completion);
#elif defined (CONFIG_MODEM_IFX)
	wait_for_completion_timeout(&spi_data->ifx_read_write_completion, 2*HZ);	
	if(ifx_ret_count==0)
	{	
		ifx_spi_set_mrdy_signal(0);  
		u32register = readl(IO_ADDRESS(0x6000d1b8));
		//lge_debug[D_SPI].enable = 1;
		printk("%s -u32register = %08X, SRDY = %d\n", __FUNCTION__, u32register, ((u32register>>5)&0x00000001)); 
	}
/*
 * Function is called from user space to send data to MODEM, it setups the transmission, enable MRDY signal and
 * waits for SRDY signal HIGH from MDOEM. Then starts transmission and reception of data to and from MODEM.
 * Once data read from MODEM is transferred to TTY core flip buffers, then "ifx_read_write_completion" is set
 * and this function returns number of bytes sent to MODEM
 */
static int
ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
	struct ifx_spi_data *spi_data = (struct ifx_spi_data *)tty->driver_data;
	int i=0;

	if( !buf ){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Buffer NULL\n");
		return 0;
	}
	if(!count){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Count is ZERO\n");
		return 0;
	}
	//printk("%s \n", __FUNCTION__) ;
	LOCK(&spi_sync_mutex);

	ifx_ret_count = 0;
	spi_data->ifx_tty = tty;
	spi_data->ifx_tty->low_latency = 1;

	ifx_spi_buf = buf;
	ifx_spi_count = count;

	ifx_master_initiated_transfer = 1;
	if(!gpio_get_value(TEGRA_GPIO_PO0))
		ifx_spi_set_mrdy_signal(1);

	UNLOCK(&spi_sync_mutex);

	// wait_for_completion(&spi_data->ifx_read_write_completion);
	wait_for_completion_timeout(&spi_data->ifx_read_write_completion, 2*HZ);
	if(ifx_ret_count==0){
		ifx_spi_set_mrdy_signal(0);
		printk("%s - timeout!! \n", __FUNCTION__);
	}

	init_completion(&spi_data->ifx_read_write_completion);

	return ifx_ret_count; /* Number of bytes sent to the device */
}
Пример #3
0
static void 
ifx_spi_handle_work(struct work_struct *work)
{
	struct ifx_spi_data *spi_data = container_of(work, struct ifx_spi_data, ifx_work);
	if (!ifx_master_initiated_transfer){
		ifx_spi_setup_transmission();
		ifx_spi_set_mrdy_signal(1);
		ifx_spi_send_and_receive_data(spi_data);
		/* Once data transmission is completed, the MRDY signal is lowered */
		if((ifx_sender_buf_size == 0)  && (ifx_receiver_buf_size == 0)){
			ifx_spi_set_mrdy_signal(0);
			ifx_spi_buffer_initialization();
		}

		/* We are processing the slave initiated transfer in the mean time Mux has requested master initiated data transfer */
		/* Once Slave initiated transfer is complete then start Master initiated transfer */
		if(ifx_master_initiated_transfer == 1){
		/* It is a condition where Slave has initiated data transfer and both SRDY and MRDY are high and at the end of data transfer		
	 	* MUX has some data to transfer. MUX initiates Master initiated transfer rising MRDY high, which will not be detected at Slave-MODEM.
	 	* So it was required to rise MRDY high again */
	 		udelay(100);//TI JANGHAN
	 		//udelay(10);// reduce delay for performnace
            ifx_spi_set_mrdy_signal(1);
		}
	}
	else{
		ifx_spi_setup_transmission();     
		ifx_spi_send_and_receive_data(spi_data);
		/* Once data transmission is completed, the MRDY signal is lowered */
		if(ifx_sender_buf_size == 0){
			if(ifx_receiver_buf_size == 0){		
				ifx_spi_set_mrdy_signal(0);
				udelay(100);////TI JANGHAN
				//udelay(10);// reduce delay for performance
				ifx_spi_buffer_initialization();
			}
			ifx_master_initiated_transfer = 0;
			complete(&spi_data->ifx_read_write_completion);
		}
	}
}
static void
ifx_spi_handle_work(struct work_struct *work)
{
	struct ifx_spi_data *spi_data = container_of(work, struct ifx_spi_data, ifx_work);
	int timer_result;
	volatile int check_resume ;
	volatile int check_suspend ;
	volatile int check_count ;

	if(spi_data->packet_count < SAFE_GUARD)
		spi_data->packet_count++;

	check_suspend = spi_data->is_suspend ;
	check_count = 0 ;
	while(1){
		if(!check_suspend)
			break ;

		msleep(1) ;
		check_suspend = spi_data->is_suspend ;
		check_count++ ;
		if(check_count > 1000)
			break ;
	}
	if(check_count != 0)
		printk("%s check count %d \n", __FUNCTION__, check_count) ;

	if (!ifx_master_initiated_transfer){
		// printk( "slave start\n");
		LOCK(&spi_sync_mutex);
		ifx_spi_setup_transmission();
		if(!gpio_get_value(TEGRA_GPIO_PO0))
			ifx_spi_set_mrdy_signal(1);
		ifx_spi_send_and_receive_data(spi_data);
		/* Once data transmission is completed, the MRDY signal is lowered */
		if((ifx_sender_buf_size == 0)  && (ifx_receiver_buf_size == 0)){
			ifx_spi_set_mrdy_signal(0);
			ifx_spi_buffer_initialization();
			if(spi_data->packet_count < SAFE_GUARD)
				my_check_delay(2*MRDY_DELAY_TIME) ;
			else
				my_check_delay(MRDY_DELAY_TIME) ;
			// udelay(2*MRDY_DELAY_TIME) ;
		}
		UNLOCK(&spi_sync_mutex);
		/* We are processing the slave initiated transfer in the mean time Mux has requested master initiated data transfer */
		/* Once Slave initiated transfer is complete then start Master initiated transfer */
		if(ifx_master_initiated_transfer == 1){
		/* It is a condition where Slave has initiated data transfer and both SRDY and MRDY are high and at the end of data transfer
	 	* MUX has some data to transfer. MUX initiates Master initiated transfer rising MRDY high, which will not be detected at Slave-MODEM.
	 	* So it was required to rise MRDY high again */
			if(!gpio_get_value(TEGRA_GPIO_PO0))
				ifx_spi_set_mrdy_signal(1);
		}
		//printk( "slave end\n");
	}
	else{
		//printk( "master start\n");
		ifx_spi_setup_transmission();
		ifx_spi_send_and_receive_data(spi_data);
		/* Once data transmission is completed, the MRDY signal is lowered */
		if(ifx_sender_buf_size == 0){
			if(ifx_receiver_buf_size == 0){
				ifx_spi_set_mrdy_signal(0);
				ifx_spi_buffer_initialization();
				if(spi_data->packet_count < SAFE_GUARD)
					my_check_delay(2*MRDY_DELAY_TIME) ;
				else
					my_check_delay(MRDY_DELAY_TIME) ;
				//udelay(2*MRDY_DELAY_TIME) ;
			}
			ifx_master_initiated_transfer = 0;
			complete(&spi_data->ifx_read_write_completion);
		}
		//printk( "master end\n");
	}
	//printk( "tegra_spi_workerthread / End\n");
}
Пример #5
0
static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, int count)
{	
	struct ifx_spi_data *spi_data = (struct ifx_spi_data *)tty->driver_data;

	if(spi_data==NULL)
	{
		IFX_SPI_PRINTK("failed : spi_data is null");
		return 0;
	}

	// spi suspend check and spi_tegra suspend check 
	if(spi_data->is_suspended ||spi_tegra_is_suspend(spi_data->spi))
	{
		IFX_SPI_PRINTK("SPI suspend : %d, SPI Tegra suspend : %d",spi_data->is_suspended,spi_tegra_is_suspend(spi_data->spi));
		return -1;
	}



	spi_data->ifx_ret_count = 0;
	spi_data->ifx_tty = tty;
	spi_data->ifx_tty->low_latency = 1;

#ifdef IFX_SPI_SPEED_MEASUREMENT
	int id = tty->index; // spi no.
	unsigned long diff;
	fWrite[id] = 1;
	uiTxlen[id] = count + IFX_SPI_HEADER_SIZE;
	//ulStart = getuSecTime();
	do_gettimeofday(&ulStart[id]); //RTC(Real Time Clock)의 현재 실행시간
#endif

	if( !buf )
	{
		IFX_SPI_PRINTK("\t Buffer NULL");
		return spi_data->ifx_ret_count;
	}
	
	if(!count)
	{
		IFX_SPI_PRINTK("\t Count is ZERO");
		return spi_data->ifx_ret_count;
	}
	
	IFX_SPI_DEBUG("**** \n");

#ifdef LGE_DUMP_SPI_BUFFER
	dump_spi_buffer("ifx_spi_write()", buf, count); 
#endif

	spi_data->ifx_master_initiated_transfer  = 1;
	spi_data->ifx_spi_buf  = buf;
	spi_data->ifx_spi_count  = count;	
	ifx_spi_set_mrdy_signal(1);
	wait_for_completion_timeout(&spi_data->ifx_read_write_completion,  2*HZ);  //3ms -> 500ms


	//To check the spi retry count when data transmit..
	if(spi_data->ifx_ret_count == 0) 
	{	
		int pin_val;	
		pin_val = gpio_get_value(IFX_SRDY);
		ifx_spi_set_mrdy_signal(0); 
		IFX_SPI_PRINTK("spi tx timeout!! SRDY : %d , buf : 0x%x, count : %d",pin_val,buf,count);
		IFX_SPI_PRINTK("ifx_master_initiated_transfer : %d, is_suspended : %d, tegra_suspend : %d",
		spi_data->ifx_master_initiated_transfer,spi_data->is_suspended,spi_tegra_is_suspend(spi_data->spi));

#ifdef LGE_DUMP_SPI_BUFFER		
		ifx_dump_spi_buffer("ifx_spi_write -- fail()", buf, count);		
#endif

		init_completion(&spi_data->ifx_read_write_completion);

		return -2; /* To Check error */

	}

#ifdef IFX_SPI_SPEED_MEASUREMENT
	//ulEnd = getuSecTime() - ulStart;
	do_gettimeofday(&ulEnd[id]);
	diff = (ulEnd[id].tv_sec - ulStart[id].tv_sec) * 1000 * 1000; //sec
	diff = (diff + (ulEnd[id].tv_usec - ulStart[id].tv_usec));
	ulTxThroughtput[id] = ((uiTxlen[id]*8*1000)/diff);
	IFX_SPI_PRINTK("					[SPI %d] : TX time = %09d usec; %04d bytes; %06lu Kbps", 
				id, diff, IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE, 
				((IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE)*8*1000)/diff);
	uiTxlen[id];
	fWrite[id] = 0;
#endif
	
	init_completion(&spi_data->ifx_read_write_completion);

	return spi_data->ifx_ret_count; /* Number of bytes sent to the device */
}
Пример #6
0
static unsigned int ifx_spi_sync_read_write(struct ifx_spi_data *spi_data, unsigned int len)
{
	bool spi_suspend_failed;

	int status;
	int ipc_check;
	struct spi_message	m;
	struct spi_transfer	t = {
					    .tx_buf		= spi_data->ifx_tx_buffer,
			                    .rx_buf		= spi_data->ifx_rx_buffer,
					    .len		= len,
				    };

#ifdef IFX_SPI_TEGRA_TRANSFER_DURATION	
	static struct timeval transfer_start_time;
	static struct timeval transfer_end_time;
	unsigned long duration_time;
#endif

	spi_message_init(&m);
	spi_message_add_tail(&t, &m);

	IFX_SPI_DEBUG("");	
	if (spi_data->spi == NULL)
	{
		IFX_SPI_PRINTK("spi_data->spi = NULL");			
		status = -ESHUTDOWN;
	}
	else
	{
#ifdef IFX_SPI_TEGRA_TRANSFER_DURATION		
		IFX_SPI_PRINTK("!!! spi_transfer start !!!");
		do_gettimeofday(&transfer_start_time);		
		status = spi_sync(spi_data->spi, &m);
		do_gettimeofday(&transfer_end_time);
		duration_time = (transfer_end_time.tv_usec - transfer_start_time.tv_usec); //sec		
		IFX_SPI_PRINTK("!!! spi_transfer end is %06d ms  !!!", (duration_time/1000)); //milisec
#else		
		status = spi_sync(spi_data->spi, &m);
#endif
	}

	if (status == 0)
	{          
		status = m.status;
		if (status == 0)
		{
			status = m.actual_length;
		}
        	//reset 'count_transfer_failed' to zero, if spi transter succeeds at least one out of five times
	        count_transfer_failed = 0;		
	}
        else
	{
		ipc_check = ifx_modem_communicating();
		if(ipc_check == 0) 
		{
			IFX_SPI_PRINTK("transmission unsuccessful, [spi_sync] status:%d, count_Failed:%d\n", status, count_transfer_failed);
				
			spi_suspend_failed = spi_tegra_suspend_failed(spi_data->spi);
			if (spi_suspend_failed)
			{
				IFX_SPI_PRINTK("kernel_restart!!!, spi_suspend_failed=%d \n", spi_suspend_failed);		 
				kernel_restart(NULL);
			 }				
		}
		//increase 'count_transfer_failed', when spi transter fails
		count_transfer_failed++;		
    }
#ifdef IFX_SPI_TX_RX_BUF
        IFX_SPI_PRINTK("SPI TX BUFFER: ");
        for(i=0;i<16;i++)
	{
        	printk( "%02x ",spi_data->ifx_tx_buffer[i]);
        }
        IFX_SPI_PRINTK("\n");
        
        IFX_SPI_PRINTK("SPI RX BUFFER : ");
        for(i=0;i<16;i++)
	{	
        	printk( "%02x ",spi_data->ifx_rx_buffer[i]);
        }
#endif
	return status;
}

/*
 * Function is a Interrupt service routine, is called when SRDY signal goes HIGH. It set up transmission and
 * reception if it is a Slave initiated data transfer. For both the cases Master intiated/Slave intiated
 * transfer it starts data transfer. 
 */
static irqreturn_t ifx_spi_handle_srdy_irq(int irq, void *handle)
{
	struct ifx_spi_data *spi_data = (struct ifx_spi_data *)handle;
	int pin_val;	
	IFX_SPI_DEBUG("");

#ifdef IFX_TEGRA_EDGE_TRIGGER
	pin_val = gpio_get_value(IFX_SRDY);
	IFX_SPI_DEBUG("pin_val = %d", pin_val);

       if(pin_val == 0)
       {
	       printk("[SPI][SRDY_IRQ] pin value is ZERO.. Return!! \n");
		 IFX_SPI_DEBUG(" IRQF_TRIGGER_FALLING in the srdy irq is ignore !!! \n");
        	 return IRQ_HANDLED;
       }
#endif	   

#if 0	  
	if(spi_data && spi_data->ifx_tty)	//add to prevent the irq of srdy until spi opening
	{
		IFX_SPI_DEBUG("queue_work is done!");		
		queue_work(spi_data->ifx_wq, &spi_data->ifx_work);    
	}
	else
	{
		IFX_SPI_PRINTK("Unexpected interrupt happen!");	
		IFX_SPI_PRINTK("spi_data = 0x%p, 0x%p, spi_data->ifx_tty =0x%p", spi_data, spi_data->ifx_tty);			
	}
#else

#ifdef WAKE_LOCK_RESUME // HZ is 1sec
		IFX_SPI_DEBUG("[IFX_SRDY] wake lock : 0x%lx", &ifx_gspi_data->wake_lock);
		wake_lock_timeout(&ifx_gspi_data->wake_lock, msecs_to_jiffies(500));	//5,, Unexpected interrupt or power consumption
#endif	
	IFX_SPI_DEBUG("queue_work is done!");		
	queue_work(spi_data->ifx_wq, &spi_data->ifx_work);	  
#endif
	return IRQ_HANDLED; 
}


// ifx_master_initiated_transfer = 1; --> set called by ifx_spi_write() 
// ifx_master_initiated_transfer = 0; --> default 
static void ifx_spi_handle_work(struct work_struct *work)
{
	bool spi_tegra_suspended;

	struct ifx_spi_data *spi_data = container_of(work, struct ifx_spi_data, ifx_work);

#ifdef IFX_SPI_SPEED_MEASUREMENT
	int id = 0;
	unsigned long diff;
#endif

	IFX_SPI_DEBUG( " start");		
	// 20120904 jisil.park
    unsigned long reg;
    int pm_off_count;

    if(1 == spi_data->is_suspended)
	{
	   pm_off_count = 1;
	   printk("[SPI][handle_work] ifx_spi_handle_work INFO spi_data->is_suspended is (0x%x)\n", spi_data->is_suspended);

	   //wait for ap to return to resume state with a worst case scenario of 5sec
	   do
	   {		   
		   mdelay(1);
		   pm_off_count++;
		   
	   }while((1 == spi_data->is_suspended) && (pm_off_count<(5*200)));

	   printk("[EBS] ifx_spi_handle_work INFO EXIT is_suspend = 0x%x pm_off_count=%d\n", spi_data->is_suspended, pm_off_count);

	   if(1 == spi_data->is_suspended)
	   {
		  // To Do how to handle the PM OFF state during 1sec
		  printk("[SPI][handle_work] ifx_spi_handle_work error is_suspended is (0x%x)\n",spi_data->is_suspended);
	   }
    }
    // 20120904 jisil.park
	
	/* add to wait tx/rx data when tegra spi is suspended*/
	spi_tegra_suspended = spi_tegra_is_suspend(spi_data->spi);
	if (spi_tegra_suspended) 
	{
		IFX_SPI_PRINTK("spi_tegra is not resume !, spi_tegra_suspended = %d\n",spi_tegra_suspended);
		return;		
	}

	if (!spi_data->ifx_master_initiated_transfer)
	{
		IFX_SPI_TX_DEBUG("CP Start =================> \n");
#ifdef IFX_SPI_SPEED_MEASUREMENT
		do_gettimeofday(&ulStart[id]);
#endif		
		ifx_spi_setup_transmission(spi_data);
		ifx_spi_set_mrdy_signal(1);
		ifx_spi_send_and_receive_data(spi_data);

#ifdef IFX_SPI_SPEED_MEASUREMENT
		do_gettimeofday(&ulEnd[id]);
		diff = (ulEnd[id].tv_sec - ulStart[id].tv_sec) * 1000 * 1000 ;
		diff = (diff + (ulEnd[id].tv_usec - ulStart[id].tv_usec));
		ulRxThroughtput[id] = ((uiRxlen[id]*8*1000)/diff);
		IFX_SPI_PRINTK("[SPI %d] : RX time = %09d usec; %04d bytes; %06lu Kbps", 
						id, diff, IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE, 
						((IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE)*8*1000)/diff);
#endif

		
		/* Once data transmission is completed, the MRDY signal is lowered */
		if((spi_data->ifx_sender_buf_size == 0)  && (spi_data->ifx_receiver_buf_size == 0))
		{
			ifx_spi_set_mrdy_signal(0);
			ifx_spi_buffer_initialization(spi_data);
		}
		/* We are processing the slave initiated transfer in the mean time Mux has requested master initiated data transfer */
		/* Once Slave initiated transfer is complete then start Master initiated transfer */
		if(spi_data->ifx_master_initiated_transfer == 1)  //why check ? already ifx_master_initiated_transfer = 0
		{
		/* It is a condition where Slave has initiated data transfer and both SRDY and MRDY are high and at the end of data transfer		
	 	* MUX has some data to transfer. MUX initiates Master initiated transfer rising MRDY high, which will not be detected at Slave-MODEM.
	 	* So it was required to rise MRDY high again */
			udelay(MRDY_DELAY_TIME) ;	 	
	                ifx_spi_set_mrdy_signal(1);    		
		}
		IFX_SPI_TX_DEBUG("CP End =================> \n");			
	}
	else
	{
		IFX_SPI_TX_DEBUG("Interrupt by AP25 ===========> \n");		
		
		ifx_spi_setup_transmission(spi_data);     
			
#if defined(LGE_DUMP_SPI_BUFFER)
	dump_spi_buffer("SPI TX", &spi_data->ifx_tx_buffer[4], COL_SIZE);
#endif		
		
		ifx_spi_send_and_receive_data(spi_data);

		/* Once data transmission is completed, the MRDY signal is lowered */
		if(spi_data->ifx_sender_buf_size == 0)
		{
			if(spi_data->ifx_receiver_buf_size == 0)
			{		
				ifx_spi_set_mrdy_signal(0);
				udelay(MRDY_DELAY_TIME) ;				
				ifx_spi_buffer_initialization(spi_data);
			}

			IFX_SPI_TX_DEBUG("ifx_master_initiated_transfer set =  0 <============== \n");		
			spi_data->ifx_master_initiated_transfer = 0;
			complete(&spi_data->ifx_read_write_completion);
		}
	}

#ifdef IFX_SPI_TX_RX_THROUGHTPUT
	if(uiTxlen[spi_data->mdm_tty->index] || uiRxlen[spi_data->mdm_tty->index]) 
	{
		 //ulEnd = getuSecTime() - ulStart;
		 do_gettimeofday(&ulEnd[spi_data->ifx_tty->index]);
		 
		 uidiff[spi_data->ifx_tty->index] = (ulEnd[spi_data->ifx_tty->index].tv_sec - ulStart[spi_data->ifx_tty->index].tv_sec) * 1000 * 1000 ;
		 uidiff[spi_data->ifx_tty->index] = uidiff[spi_data->ifx_tty->index] + (ulEnd[spi_data->ifx_tty->index].tv_usec - ulStart[spi_data->ifx_tty->index].tv_usec);
		 ulTxThroughtput[spi_data->ifx_tty->index] = ((uiTxlen[spi_data->ifx_tty->index]*8*1000)/uidiff[spi_data->ifx_tty->index]);
		 ulRxThroughtput[spi_data->ifx_tty->index] = ((uiRxlen[spi_data->ifx_tty->index]*8*1000)/uidiff[spi_data->ifx_tty->index]);

	 	IFX_SPI_PRINTK("[SPI %d] time	= %d us, Tx(%dbytes) = %luKbps, Rx(%dbytes) = %luKbps, Max(%dbytes) = %luKbps\n", 
						spi_data->ifx_tty->index, uidiff[spi_data->mdm_tty->index], 
						uiTxlen[spi_data->ifx_tty->index], ulTxThroughtput[spi_data->ifx_tty->index], 
						uiRxlen[spi_data->ifx_tty->index], ulRxThroughtput[spi_data->ifx_tty->index],
						IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE, 
						((IFX_SPI_MAX_BUF_SIZE+IFX_SPI_HEADER_SIZE)*8*1000)/uidiff[spi_data->ifx_tty->index]);

		uiTxlen[spi_data->ifx_tty->index] = uiRxlen[spi_data->ifx_tty->index] = 0;
		fWrite[spi_data->ifx_tty->index] = 0;
	}
#endif

	IFX_SPI_DEBUG( " end");
}
Пример #7
0
static int 
ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, int count)
{	
	struct ifx_spi_data *spi_data = (struct ifx_spi_data *)tty->driver_data;
        ifx_ret_count = 0;

#ifdef LGE_DUMP_SPI_BUFFER
    dump_spi_buffer("ifx_spi_write()", buf, count);
#elif defined(LGE_VT_DATA_DUMP)
    if (count == 167) // 167 means 160(MUX data) + 7 (DLC Frame Header + Tails)
    {
       // dump_spi_wr_buffer(buf, count);
    }
#endif

// hgahn
	if(spi_data->ifx_spi_lock)
		return ifx_ret_count;

	spi_data->ifx_tty = tty;
	spi_data->ifx_tty->low_latency = 1;
	if( !buf ){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Buffer NULL\n");
		return ifx_ret_count;
	}
	if(!count){
		printk("File: ifx_n721_spi.c\tFunction: int ifx_spi_write()\t Count is ZERO\n");
		return ifx_ret_count;
	}
	ifx_master_initiated_transfer = 1;
	ifx_spi_buf = buf;
	ifx_spi_count = count;

// LGE_CHANGE_S [[email protected]] 2010-10-11 to retry IPC transmission when SRDY is not signaled by CP
	/* original code
	ifx_spi_set_mrdy_signal(1);	
		
	wait_for_completion(&spi_data->ifx_read_write_completion);
	*/
	{
		int i, max_retry_count=8;
		unsigned long timeout=HZ;
		long rc;

		for (i=0 ; i<max_retry_count ; i++) {
			// signal master ready
			ifx_spi_set_mrdy_signal(1);

			// wait for completion with timeout
			rc = wait_for_completion_timeout(
					&spi_data->ifx_read_write_completion,
					timeout);

			if (rc == 0) {		// timeout expired, retry
				printk("***** unable to detect SREADY within %lu, RETRY (counter=%d) *****\n", timeout, i+1);
				// lower master ready
				ifx_spi_set_mrdy_signal(0);

//<*****@*****.**> LGE_CHANGE_S  ril_retry_count
				if(i == (max_retry_count-1))
				{
					{
						set_modem_alive(0);
						ifx_ril_is_modem_alive = 0;
					}
				}
//<*****@*****.**> LGE_CHANGE_E  ril_retry_count
				// retry after delay
				udelay(100);		// 20 u sec delay
			} else {			// success or failure
				//printk("wait_for_completion_timeout timeout=%ld\n", timeout);
//<*****@*****.**> LGE_CHANGE_S  ril_retry_count
				if(!ifx_ril_is_modem_alive)
				{
					set_modem_alive(1);
					ifx_ril_is_modem_alive = 1;
				}
//<*****@*****.**> LGE_CHANGE_E  ril_retry_count
				break;
			}
		}
	}
// LGE_CHANGE_E [[email protected]] 2010-10-11 to retry IPC transmission when SRDY is not signaled by CP

	init_completion(&spi_data->ifx_read_write_completion);
	return ifx_ret_count; /* Number of bytes sent to the device */
}