Пример #1
0
void bs_hw_done()//bool dealloc
{
    
    if ( !(broadsheet_ignore_hw_ready() || broadsheet_force_hw_not_ready()) )
    {
        // Wait until any pending operations are done before shutting down.
        //
        einkfb_debug("Waiting for HRDY before shutting down...\n");
        wait_for_ready();
    }
    
#ifdef MXC31
#ifdef CONFIG_MACH_MX31ADS
    // Reset the level translator for the two GPIO inputs (HIRQ and HRDY)
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
    mdelay(100);    // Pause 100 ms to allow level translator to settle
#elif  CONFIG_MACH_MARIO_MX
    mxc_free_gpio(BROADSHEET_RST_LINE);
#endif

#ifdef USE_BS_IRQ
    disable_irq(BROADSHEET_HIRQ_IRQ);
    free_irq(BROADSHEET_HIRQ_IRQ, NULL);
#endif

    mxc_free_gpio(BROADSHEET_HIRQ_LINE);
    mxc_free_gpio(BROADSHEET_HRDY_LINE);
#endif
    einkfb_debug("Released Broadsheet GPIO pins and IRQs\n");
}
Пример #2
0
static void fslepdc_send_update_retry(struct work_struct *work)
{
    if (fslepdc_removed)
	return;

    einkfb_debug("Retrying update, count = %d\n", fslepdc_send_update_retry_counter);
    fslepdc_send_update(&fslepdc_send_update_retry_data, FSLEPDC_UPDATE_RETRY);
}
Пример #3
0
static irqreturn_t bs_irq_handler (int irq, void *data, struct pt_regs *r)
{
    u16 irq_status;

    // Check Broadsheet general IRQs

    irq_status = bs_cmd_rd_reg(BS_INTR_RAW_STATUS_REG);
    einkfb_debug("BS_INTR_RAW_STATUS_REG = 0x%04X\n", irq_status);

    irq_status = bs_cmd_rd_reg(BS_DE_INTR_RAW_STATUS_REG);
    einkfb_debug("BS_DE_INTR_RAW_STATUS_REG = 0x%04X\n", irq_status);

    // Clear all interrupt flags
    bs_cmd_wr_reg(BS_INTR_RAW_STATUS_REG, BS_ALL_IRQS);
    bs_cmd_wr_reg(BS_DE_INTR_RAW_STATUS_REG, BS_DE_ALL_IRQS);

   return IRQ_HANDLED;
}
Пример #4
0
// Scheduled loop for doing IO on framebuffer-sized buffers.
//
static int bs_io_buf(u32 data_size, u16 *data, bool which)
{
//    display_port_t disp = BROADSHEET_DISPLAY_NUMBER;
    int result = EINKFB_FAILURE;

    dd_printk("[D]    len=%i\n", data_size);

    einkfb_debug_full("size    = %d\n", data_size);

    if ( BS_READY() )
    {
        int     i = 0, j, length = (EINKFB_MEMCPY_MIN >> 1), num_loops = data_size/length,
                remainder = data_size % length;
        bool    done = false;
        
        if ( 0 != num_loops )
            einkfb_debug("num_loops @ %d bytes = %d, remainder = %d\n",
                (length << 1), num_loops, (remainder << 1));
        
        result = EINKFB_SUCCESS;
        
        // Read/write EINKFB_MEMCPY_MIN bytes (hence, divide by 2) at a time.  While
        // there are still bytes to read/write, yield the CPU.
        //
        do
        {
            if ( 0 >= num_loops )
                length = remainder;

            for ( j = 0; j < length; j++)
            {
                if ( BS_WR == which )
//                    ipu_adc_write_cmd(disp, DAT, (uint32_t)data[i + j], 0, 0);
                    ipu_adc_write_cmd(DAT, (uint32_t)data[i + j]);
                else
//                    data[i + j] = (u16)(ipu_adc_read_data(disp) & 0x0000FFFF);
                    data[i + j] = (u16)(ipu_adc_read_data() & 0x0000FFFF);
            }
                
            i += length;
            
            if ( i < data_size )
            {
                EINKFB_SCHEDULE();
                num_loops--;
            }
            else
                done = true;
        }
        while ( !done );
    }

    return ( result );
}
Пример #5
0
static void fslepdc_set_orientation(void)
{
    // The displays for Whitney and Tequila are mounted upside down from Finkle.  It
    // doesn't really matter on Yoshi, so we'll set it to Finkle's orientation.
    // Any devices that we don't know about yet will just be considered to be in
    // the default, upright orientation.
    //
    if ( mx50_board_is(BOARD_ID_YOSHI) || mx50_board_is(BOARD_ID_FINKLE) )
    {
        fslepdc_orientation = fslepdc_orientation_ud;
        fslepdc_rotate = fslepdc_rotate_ud;
        
        einkfb_debug("orientation is upside down\n");
    }
    else
    {
        fslepdc_orientation = fslepdc_orientation_ur;
        fslepdc_rotate = fslepdc_rotate_ur;
        
        einkfb_debug("orientation is upright\n");
    }
}
Пример #6
0
int einkfb_schedule_timeout(unsigned long hardware_timeout, einkfb_hardware_ready_t hardware_ready, void *data, bool interruptible)
{
    int result = EINKFB_SUCCESS;
    
    if ( hardware_timeout && hardware_ready )
    {
        if ( FORCE_INTERRUPTIBLE() || interruptible )
            result = einkfb_schedule_timeout_guts(hardware_timeout, hardware_ready, data, INTERRUPTIBLE);
        else
            result = einkfb_schedule_timeout_uninterruptible(hardware_timeout, hardware_ready, data);
    }
    else
    {
        // Yield the CPU with schedule.
        //
        einkfb_debug("Yielding CPU with schedule.\n");
        schedule();
    }
    
    return ( result );
}
Пример #7
0
static char *fslepdc_waveform_version_io(char *path)
{
    char *result = NULL;
    
    // If we're requesting that the in-use waveform version be returned...
    //
    if ( EINKFB_READ_WFV(path) )
    {
        // ...then do that now.
        //
	einkwf_set_buffer(fslepdc_waveform_proxy);
        result = einkwf_get_waveform_version_string(eink_waveform_version_string);
    }
    else
    {
        // ...otherwise, read in the waveform from the passed-in path.
        //
        einkfb_debug("waveform path = %s\n", path);
    }
    
    return ( result );
}
Пример #8
0
static int einkfb_schedule_timeout_guts(unsigned long hardware_timeout, einkfb_hardware_ready_t hardware_ready, void *data, bool interruptible)
{
    unsigned long start_time = jiffies, stop_time = start_time + hardware_timeout,
        timeout = CONTROLLER_COMMON_TIMEOUT_MIN;
    int result = EINKFB_SUCCESS;

    // Ask the hardware whether it's ready or not.  And, if it's not ready, start yielding
    // the CPU for CONTROLLER_COMMON_TIMEOUT_MIN jiffies, increasing the yield time up to
    // CONTROLLER_COMMON_TIMEOUT_MAX jiffies.  Time out after the requested number of
    // of jiffies has occurred.
    //
    while ( !(*hardware_ready)(data) && time_before_eq(jiffies, stop_time) )
    {
        timeout = min(timeout++, CONTROLLER_COMMON_TIMEOUT_MAX);
        
        if ( interruptible )
            schedule_timeout_interruptible(timeout);
        else
            schedule_timeout(timeout);
    }

    if ( time_after(jiffies, stop_time) )
    {
       einkfb_print_crit("Timed out waiting for the hardware to become ready!\n");
       result = EINKFB_FAILURE;
    }
    else
    {
        // For debugging purposes, dump the time it took for the hardware to
        // become ready if it was more than CONTROLLER_COMMON_TIMEOUT_MAX.
        //
        stop_time = jiffies - start_time;
        
        if ( CONTROLLER_COMMON_TIMEOUT_MAX < stop_time )
            einkfb_debug("Timeout time = %ld\n", stop_time);
    }

    return ( result );    
}
Пример #9
0
void einkfb_set_contrast(contrast_t contrast)
{
    switch ( contrast )
    {
    case contrast_lightest:
    case contrast_lighter:
    case contrast_light:
    case contrast_medium:
    case contrast_dark:
    case contrast_darker:
    case contrast_darkest:
    case contrast_invert:
    case contrast_off:
        einkfb_contrast = contrast;
        break;

    default:
        einkfb_contrast = contrast_off;
        break;
    }

    einkfb_debug("contrast = %d\n", einkfb_contrast);
}
Пример #10
0
bool bs_quickly_hw_init(void)
{

	bool result = true;
	if (bsaddr == NULL)
		{
		bsaddr = ioremap(0x10000000, 4);
		}
	if ((unsigned int)bsaddr  < 0xa0000000)
		{
		iounmap(bsaddr);
		bsaddr = ioremap(0x10000000, 4);
		}
//reset broadsheet

	// GPC7  EINK_3.3V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 28);
		__raw_writel(gpcon | (0x1 << 28), S3C64XX_GPCCON);		
	//GPC7 EINK_3.3V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<7));
		__raw_writel(gpdata,S3C64XX_GPCDAT);

	//GPC6 EINK_1.8V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 24);
		__raw_writel(gpcon | (0x1 << 24), S3C64XX_GPCCON);
	
	//GPC6 EINK_1.8V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<6));
		__raw_writel(gpdata,S3C64XX_GPCDAT);
	
	//GPP2 OSC_EN config output
		gpcon = __raw_readl(S3C64XX_GPPCON);
		gpcon  = (gpcon & ~(3<<4));
		 __raw_writel(gpcon|(0x1<<4), S3C64XX_GPPCON);
	//GPP2 OSC_EN set high
		gpdata = __raw_readl(S3C64XX_GPPDAT);
		gpdata =(gpdata & ~(1<<2));
		__raw_writel(gpdata|(0x1<<2),S3C64XX_GPPDAT);
		mdelay(10);

	//GPP9 HnRST config output
      HIGH_RESET_PIN;	
	gpcon = __raw_readl(S3C64XX_GPPCON);
	gpcon  = (gpcon & ~(3<<18));
	__raw_writel(gpcon|(0x1<<18), S3C64XX_GPPCON);

      HIGH_RESET_PIN;
	udelay(100);
      LOW_RESET_PIN;
	udelay(100);
      HIGH_RESET_PIN;

//setup HD/C signalconfig
	gpcon = __raw_readl(S3C64XX_GPOCON);
	gpcon =(gpcon & ~(3<<4));
	__raw_writel(gpcon|(0x1<<4),S3C64XX_GPOCON);

	gpdata = __raw_readl(S3C64XX_GPODAT);
        gpdata =(gpdata & ~(1<<2));
        __raw_writel(gpdata|(0x1<<2),S3C64XX_GPODAT);

	//GPO3 HIRQ config input
		gpcon = __raw_readl(S3C64XX_GPOCON);
		gpcon  = (gpcon & ~(3<<6));
		__raw_writel(gpcon, S3C64XX_GPOCON);

//now HRDY  setup to input
	gpcon = __raw_readl(S3C64XX_GPOCON);
        gpcon  = (gpcon & ~(3<<8));
        __raw_writel(gpcon, S3C64XX_GPOCON);


	sromdata = __raw_readl(S3C64XX_VA_SROMC);
        sromdata &=~(0xF<<0);
        sromdata |= (1<<3) | (1<<2) | (1<<0);
        __raw_writel(sromdata, S3C64XX_VA_SROMC);
		
	//SROM_BC0 config
		//__raw_writel((0x1<<28)|(0xf<<24)|(0x1c<<16)|(0x1<<12)|(0x6<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);
    __raw_writel((0x0<<28)|(0x0<<24)|(0xA<<16)|(0x1<<12)|(0x0<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);

	//printk(KERN_ALERT "Product id is %x\n",__raw_readw(bsaddr));
	//printk(KERN_ALERT "The new bs driver\n");

    //ipu_adc_write_cmd(CMD,0x11);
    //ipu_adc_write_cmd(DAT,0x030a);
    //ipu_adc_write_cmd(DAT,0x0123);

/*
    	ipu_adc_write_cmd(CMD,0x10);
        __raw_writew(0x02,bsaddr);

        udelay(1);

        printk(KERN_ALERT "Product id re-get is %x\n",__raw_readw(bsaddr));
        //printk(KERN_ALERT "The new bs driver\n");

    ipu_adc_write_cmd(CMD,0x10);
    ipu_adc_write_cmd(DAT,0x02);
    printk(KERN_ALERT "register 0x0002 content is 0x%4x\n",ipu_adc_read_data());
*/

#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT)  || defined(CONFIG_HW_EP1_DVT)  || defined(CONFIG_HW_EP2_DVT)			
    u16 rd_reg;
    unsigned short value = 0;	
    rd_reg = bs_cmd_rd_reg(0x00a) & ~(1 << 12);
    bs_cmd_wr_reg(0x00a, (value | (1 << 12)));		//REG[000Ah] bit 12 = 1b

 //Henry Li 0927 fro saving time in resume 	
    mdelay(4);
    
    bs_cmd_init_sys_run();
    udelay(EPD_CMD_DELAY);
    rd_reg=0;
    while(!value)
	{
		value = GET_HRDY_STATUS;
   	       udelay(50);
		rd_reg++;
		if (rd_reg > 60000)
			break;
	}
    //rd_reg = bs_cmd_rd_reg(0x0204) | (1 << 7);  // spi flash control reg: Display Engine access mode is selected.
       rd_reg = 0x99;
    bs_cmd_wr_reg(0x0204, rd_reg);
 //Henry Li 0927 fro saving time in resume 	
/* 
    udelay(EPD_CMD_DELAY);
    printk("reg[0x0204] is 0x%x\n", rd_reg);
*/    
#endif	
 //Henry Li 0927 fro saving time in resume 	
/* 
    ipu_adc_write_cmd(CMD,0x10);
    ipu_adc_write_cmd(DAT,0x02);
    printk(KERN_ALERT "register 0x0002 content is 0x%4x\n",ipu_adc_read_data());
*/
     einkfb_debug("GPIOs and IRQ set; Broadsheet has been reset\n");
#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT) 
/* //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
*/    
    bs_cmd_wr_reg(0x300, BS97_INIT_VSIZE);	//Frame Data Length Register
    											//Henry: as instruction code init it as 825
 //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
    
#endif
    return ( result );
}
Пример #11
0
bool bs_hw_init(void)
{

	bool result = true;
	bsaddr = ioremap(0x10000000, 4);

	//printk(KERN_ALERT "hello broadsheet!\n");

//reset broadsheet

	// GPC7  EINK_3.3V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 28);
		__raw_writel(gpcon | (0x1 << 28), S3C64XX_GPCCON);		
	//GPC7 EINK_3.3V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<7));
		__raw_writel(gpdata,S3C64XX_GPCDAT);

	//GPC6 EINK_1.8V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 24);
		__raw_writel(gpcon | (0x1 << 24), S3C64XX_GPCCON);
	
	//GPC6 EINK_1.8V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<6));
		__raw_writel(gpdata,S3C64XX_GPCDAT);
	
	//GPP2 OSC_EN config output
		gpcon = __raw_readl(S3C64XX_GPPCON);
		gpcon  = (gpcon & ~(3<<4));
		 __raw_writel(gpcon|(0x1<<4), S3C64XX_GPPCON);
	//GPP2 OSC_EN set high
		gpdata = __raw_readl(S3C64XX_GPPDAT);
		gpdata =(gpdata & ~(1<<2));
		__raw_writel(gpdata|(0x1<<2),S3C64XX_GPPDAT);
		mdelay(10);

	//GPP9 HnRST config output
	gpcon = __raw_readl(S3C64XX_GPPCON);
	gpcon  = (gpcon & ~(3<<18));
	__raw_writel(gpcon|(0x1<<18), S3C64XX_GPPCON);
	
      HIGH_RESET_PIN;
	mdelay(10);
      LOW_RESET_PIN;
      mdelay(100); 
      HIGH_RESET_PIN;


//setup HD/C signalconfig
	gpcon = __raw_readl(S3C64XX_GPOCON);
	gpcon =(gpcon & ~(3<<4));
	__raw_writel(gpcon|(0x1<<4),S3C64XX_GPOCON);

	gpdata = __raw_readl(S3C64XX_GPODAT);
        gpdata =(gpdata & ~(1<<2));
        __raw_writel(gpdata|(0x1<<2),S3C64XX_GPODAT);

	//GPO3 HIRQ config input
		gpcon = __raw_readl(S3C64XX_GPOCON);
		gpcon  = (gpcon & ~(3<<6));
		__raw_writel(gpcon, S3C64XX_GPOCON);

//now HRDY  setup to input
	gpcon = __raw_readl(S3C64XX_GPOCON);
        gpcon  = (gpcon & ~(3<<8));
        __raw_writel(gpcon, S3C64XX_GPOCON);


	sromdata = __raw_readl(S3C64XX_VA_SROMC);
        sromdata &=~(0xF<<0);
        sromdata |= (1<<3) | (1<<2) | (1<<0);
        __raw_writel(sromdata, S3C64XX_VA_SROMC);
		
	//SROM_BC0 config
		//__raw_writel((0x1<<28)|(0xf<<24)|(0x1c<<16)|(0x1<<12)|(0x6<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);
    __raw_writel((0x0<<28)|(0x0<<24)|(0xA<<16)|(0x1<<12)|(0x0<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);

	//printk(KERN_ALERT "Product id is %x\n",__raw_readw(bsaddr));
	//printk(KERN_ALERT "The new bs driver\n");
#ifdef MXC31
	for(i=0;i<100;i++)
	{
	mdelay(500);
	__raw_writew(0xffff,bsaddr);
	//printk(KERN_ALERT "write the %dth times data\n",i);
	}
#endif

#ifdef USE_BS_IRQ
    int  rqstatus;
#endif
#ifdef MXC31
    ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
            IPU_ADC_BURST_WCS,
            IPU_ADC_IFC_MODE_SYS80_TYPE2,
            16, 0, 0, IPU_ADC_SER_NO_RW
    };

    // Init DI interface
    if ( IS_NELL() || IS_MARIO() || IS_ADS() )
    {
        broadsheet_screen_height = BROADSHEET_SCREEN_HEIGHT_NELL;
        broadsheet_screen_width  = BROADSHEET_SCREEN_WIDTH_NELL;

        broadsheet_screen_size   = BROADSHEET_SCREEN_SIZE_NELL;
    }

    ipu_adc_init_panel(BROADSHEET_DISPLAY_NUMBER,
                       broadsheet_screen_width,
                       broadsheet_screen_height,
                       BROADSHEET_PIXEL_FORMAT, broadsheet_screen_size, sig, XY, 0, VsyncInternal);

    // Set IPU timing for read cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, true,
                            BROADSHEET_READ_CYCLE_TIME,
                            BROADSHEET_READ_UP_TIME,
                            BROADSHEET_READ_DOWN_TIME,
                            BROADSHEET_READ_LATCH_TIME,
                            BROADSHEET_PIXEL_CLK);
    // Set IPU timing for write cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, false,
                            BROADSHEET_WRITE_CYCLE_TIME,
                            BROADSHEET_WRITE_UP_TIME,
                            BROADSHEET_WRITE_DOWN_TIME,
                            0, 0);

    ipu_adc_set_update_mode(ADC_SYS1, IPU_ADC_REFRESH_NONE, 0, 0, 0);

    gpio_lcd_active();
    slcd_gpio_config();

#ifdef CONFIG_MACH_MX31ADS
    // Reset the level translator for the two GPIO inputs (HIRQ and HRDY)
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
#endif

#ifdef USE_BS_IRQ
    // Set up IRQ for for Broadsheet HIRQ line
    disable_irq(BROADSHEET_HIRQ_IRQ);
    set_irq_type(BROADSHEET_HIRQ_IRQ, IRQF_TRIGGER_RISING);
    rqstatus = request_irq(BROADSHEET_HIRQ_IRQ, (irq_handler_t) bs_irq_handler, 0, "eink_fb_hal_broads", NULL);
    if (rqstatus != 0) {
        einkfb_print_crit("Failed IRQ request for Broadsheet HIRQ line; request status = %d\n", rqstatus);
        result = false;
    }
#endif

     // Set up GPIO pins
    if (mxc_request_gpio(BROADSHEET_HIRQ_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HIRQ\n");
        result = false;
    }
    else {
        // Set HIRQ pin as input
        mxc_set_gpio_direction(BROADSHEET_HIRQ_LINE, 1);
    }
    if (mxc_request_gpio(BROADSHEET_HRDY_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HRDY\n");
        result = false;
    }
    else {
        // Set HRDY pin as input
        mxc_set_gpio_direction(BROADSHEET_HRDY_LINE, 1);
    }
#ifdef CONFIG_MACH_MARIO_MX
    if (mxc_request_gpio(BROADSHEET_RST_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for RST\n");
        result = false;
    }
    else {
        // Set RST pin as output and initialize to zero (it's active LOW)
        mxc_set_gpio_direction(BROADSHEET_RST_LINE, 0);
        mxc_set_gpio_dataout(BROADSHEET_RST_LINE, 0);
    }
#endif

#ifdef CONFIG_MACH_MX31ADS
    // Enable the level translator for the two GPIO inputs (HIRQ and HRDY)
    mdelay(100);    // Pause 100 ms to allow level translator to settle
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
#endif
    // Reset Broadsheet
    einkfb_debug("Sending RST signal to Broadsheet...\n");
    LOW_RESET_PIN;	//WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_RESET_VAL);     // Assert RST
    mdelay(100);    // Pause 100 ms during reset
    HIGH_RESET_PIN;
 //WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_NON_RESET_VAL); // Clear RST
    mdelay(400);    // Pause 400 ms to allow Broasheet time to come up
    einkfb_debug("Broadsheet reset done.\n");
//#ifdef TEST_BROADSHEET
//    test_broadsheet(disp);
//#endif
#endif
#ifdef USE_BS_IRQ
    // Set up Broadsheet for interrupt generation (enable all conditions)
    bs_cmd_wr_reg(BS_INTR_CTL_REG, BS_ALL_IRQS);
    bs_cmd_wr_reg(BS_INTR_RAW_STATUS_REG, BS_ALL_IRQS);

    // Enable all Broadsheet display engine interrupts
    bs_cmd_wr_reg(BS_DE_INTR_ENABLE_REG, BS_DE_ALL_IRQS);
    bs_cmd_wr_reg(BS_DE_INTR_RAW_STATUS_REG, BS_DE_ALL_IRQS);
#endif
    //ipu_adc_write_cmd(CMD,0x11);
    //ipu_adc_write_cmd(DAT,0x030a);
    //ipu_adc_write_cmd(DAT,0x0123);

/*
    	ipu_adc_write_cmd(CMD,0x10);
        __raw_writew(0x02,bsaddr);

        udelay(1);

        printk(KERN_ALERT "Product id re-get is %x\n",__raw_readw(bsaddr));
        //printk(KERN_ALERT "The new bs driver\n");
*/

#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT)  || defined(CONFIG_HW_EP1_DVT)  || defined(CONFIG_HW_EP2_DVT)			
    u16 rd_reg;
    unsigned short value = 0;	
    rd_reg = bs_cmd_rd_reg(0x00a) & ~(1 << 12);
    bs_cmd_wr_reg(0x00a, (value | (1 << 12)));		//REG[000Ah] bit 12 = 1b

 //Henry Li 0927 fro saving time in resume 	
    mdelay(4);
    
    bs_cmd_init_sys_run();
    udelay(EPD_CMD_DELAY);
    rd_reg=0;
    while(!value)
	{
		value = GET_HRDY_STATUS;
   	       udelay(50);
		rd_reg++;
		if (rd_reg > 60000)
			break;
	}
    //rd_reg = bs_cmd_rd_reg(0x0204) | (1 << 7);  // spi flash control reg: Display Engine access mode is selected.
       rd_reg = 0x99;
    bs_cmd_wr_reg(0x0204, rd_reg);
/* //Henry Li 0927 fro saving time in resume 	
    udelay(EPD_CMD_DELAY);
    printk("reg[0x0204] is 0x%x\n", rd_reg);
*/    
#endif	
/* //Henry Li 0927 fro saving time in resume 	
    ipu_adc_write_cmd(CMD,0x10);
    ipu_adc_write_cmd(DAT,0x02);
    printk(KERN_ALERT "register 0x0002 content is 0x%4x\n",ipu_adc_read_data());
*/
     einkfb_debug("GPIOs and IRQ set; Broadsheet has been reset\n");
#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT) 
/* //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
*/    
    bs_cmd_wr_reg(0x300, BS97_INIT_VSIZE);	//Frame Data Length Register
    											//Henry: as instruction code init it as 825
/* //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
*/    
#endif
    return ( result );
}
Пример #12
0
static bool fslepdc_send_update(struct mxcfb_update_data *update_data, bool retry)
{
    bool result = false;
    
    if ( update_data )
    {
        unsigned long start_time, stop_time;
        int send_update_err;
        
        // If this isn't a retry...
        //
        if ( !retry )
        {
            // ...cancel any pending retries.
            //
            cancel_delayed_work(&fslepdc_send_update_work);
            
            // But accumulate any pending retry with the new data.
            //
            if ( fslepdc_send_update_retry_counter )
            {
                struct mxcfb_rect old_retry = fslepdc_send_update_retry_data.update_region,
                                  new_retry,
                                  update    = update_data->update_region;
                u32               old_retry_right,
                                  old_retry_bot,
                                  new_retry_right,
                                  new_retry_bot,
                                  update_right,
                                  update_bot;
                
                // First, accumulate the update region.
                //
                old_retry_right  = (old_retry.left + old_retry.width)  - 1;
                old_retry_bot    = (old_retry.top  + old_retry.height) - 1;
                update_right     = (update.left    + update.width)     - 1;
                update_bot       = (update.top     + update.height)    - 1;
                
                new_retry.left   = min(old_retry.left,  update.left);
                new_retry.top    = min(old_retry.top,   update.top);
                new_retry_right  = max(old_retry_right, update_right);
                new_retry_bot    = max(old_retry_bot,   update_bot);
                
                new_retry.width  = (new_retry_right - new_retry.left)  + 1;
                new_retry.height = (new_retry_bot   - new_retry.top)   + 1;
                
                fslepdc_send_update_retry_data.update_region = new_retry;
                
                // Since it's a retry, go for the highest fidelity possible.
                //
                fslepdc_send_update_retry_data.waveform_mode = fslepdc_get_waveform_mode(WF_UPD_MODE_GC);
                fslepdc_send_update_retry_data.update_mode   = UPDATE_MODE_FULL;
                
                // Use the latest marker and temperature.
                //
                fslepdc_send_update_retry_data.update_marker = update_data->update_marker;
                fslepdc_send_update_retry_data.temp          = update_data->temp;
                
                // Copy the retry data back for this attempt.
                //
                *update_data = fslepdc_send_update_retry_data;
            }
        }
        
        // We can get errors sending updates to EPDC if it's not ready to do
        // an update yet.  So, back off and retry a few times here first
        // before scheduling a retry.
        //
        start_time = jiffies; stop_time = start_time + FSLEPDC_SU_TIMEOUT;    

        do
        {
            send_update_err = mxc_epdc_fb_send_update(update_data, NULL);
            
            if ( 0 != send_update_err )
            {
                einkfb_print_error("EPDC_send_update_error=%d:\n", send_update_err);
                schedule_timeout_uninterruptible(FSLEPDC_SU_WAIT);
            }
        }
        while ( (0 != send_update_err) && time_before_eq(jiffies, stop_time) );
        
        if ( time_after(jiffies, stop_time) )
        {
             einkfb_print_crit("EDPC_send_update_timed_out=true:\n");
        }
        else
        {
            char temp_string[16];
            
            if ( TEMP_USE_AMBIENT == update_data->temp )
                strcpy(temp_string, "ambient");
            else
                sprintf(temp_string, "%d", update_data->temp);
            
            einkfb_debug("update_data:\n");
            einkfb_debug("  rect x: %d\n", update_data->update_region.left);
            einkfb_debug("  rect y: %d\n", update_data->update_region.top);
            einkfb_debug("  rect w: %d\n", update_data->update_region.width);
            einkfb_debug("  rect h: %d\n", update_data->update_region.height);
            einkfb_debug("  wfmode: %d\n", update_data->waveform_mode);
            einkfb_debug("  update: %s\n", update_data->update_mode ? "flashing" : "non-flashing");
            einkfb_debug("  marker: %d\n", update_data->update_marker);
            einkfb_debug("  temp:   %s\n", temp_string);
            
            fslepdc_send_update_retry_counter = 0;
            result = true;
        }

        // If our attempt to send an update failed, try it again later.
        //
        if ( !result )
        {
            if ( FSLEPDC_SU_RETRIES > ++fslepdc_send_update_retry_counter )
            {
                // If this isn't a retry, use the current update data.
                //
                if ( !retry )
                    fslepdc_send_update_retry_data = *update_data;
                
                schedule_delayed_work(&fslepdc_send_update_work, FSLEPDC_SU_DELAY);
            }
            else
            {
                einkfb_print_crit("Updates are failing...\n");
            }
        }
    }
    
    return ( result );
}
Пример #13
0
bool bs_hw_init(void)
{
    bool result = true;
#ifdef USE_BS_IRQ
    int  rqstatus;
#endif
    
    ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
            IPU_ADC_BURST_WCS,
            IPU_ADC_IFC_MODE_SYS80_TYPE2,
            16, 0, 0, IPU_ADC_SER_NO_RW
    };

    // Init DI interface
    if ( IS_NELL() || IS_MARIO() || IS_ADS() )
    {
        broadsheet_screen_height = BROADSHEET_SCREEN_HEIGHT_NELL;
        broadsheet_screen_width  = BROADSHEET_SCREEN_WIDTH_NELL;
        
        broadsheet_screen_size   = BROADSHEET_SCREEN_SIZE_NELL;
    }

    ipu_adc_init_panel(BROADSHEET_DISPLAY_NUMBER,
                       broadsheet_screen_width,
                       broadsheet_screen_height,
                       BROADSHEET_PIXEL_FORMAT, broadsheet_screen_size, sig, XY, 0, VsyncInternal);

    // Set IPU timing for read cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, true,
                            BROADSHEET_READ_CYCLE_TIME,
                            BROADSHEET_READ_UP_TIME,
                            BROADSHEET_READ_DOWN_TIME,
                            BROADSHEET_READ_LATCH_TIME,
                            BROADSHEET_PIXEL_CLK);
    // Set IPU timing for write cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, false,
                            BROADSHEET_WRITE_CYCLE_TIME,
                            BROADSHEET_WRITE_UP_TIME,
                            BROADSHEET_WRITE_DOWN_TIME,
                            0, 0);

    ipu_adc_set_update_mode(ADC_SYS1, IPU_ADC_REFRESH_NONE, 0, 0, 0);

    gpio_lcd_active();
    slcd_gpio_config();

#ifdef CONFIG_MACH_MX31ADS
    // Reset the level translator for the two GPIO inputs (HIRQ and HRDY)
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
#endif

#ifdef USE_BS_IRQ
    // Set up IRQ for for Broadsheet HIRQ line
    disable_irq(BROADSHEET_HIRQ_IRQ);
    set_irq_type(BROADSHEET_HIRQ_IRQ, IRQF_TRIGGER_RISING);
    rqstatus = request_irq(BROADSHEET_HIRQ_IRQ, (irq_handler_t) bs_irq_handler, 0, "eink_fb_hal_broads", NULL);
    if (rqstatus != 0) {
        einkfb_print_crit("Failed IRQ request for Broadsheet HIRQ line; request status = %d\n", rqstatus);
        result = false;
    }
#endif

     // Set up GPIO pins
    if (mxc_request_gpio(BROADSHEET_HIRQ_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HIRQ\n");
        result = false;
    }
    else {
        // Set HIRQ pin as input
        mxc_set_gpio_direction(BROADSHEET_HIRQ_LINE, 1);
    }
    if (mxc_request_gpio(BROADSHEET_HRDY_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HRDY\n");
        result = false;
    }
    else {
        // Set HRDY pin as input
        mxc_set_gpio_direction(BROADSHEET_HRDY_LINE, 1);
    }
#ifdef CONFIG_MACH_MARIO_MX
    if (mxc_request_gpio(BROADSHEET_RST_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for RST\n");
        result = false;
    }
    else {
        // Set RST pin as output and initialize to zero (it's active LOW)
        mxc_set_gpio_direction(BROADSHEET_RST_LINE, 0);
        mxc_set_gpio_dataout(BROADSHEET_RST_LINE, 0);
    }
#endif

#ifdef CONFIG_MACH_MX31ADS
    // Enable the level translator for the two GPIO inputs (HIRQ and HRDY)
    mdelay(100);    // Pause 100 ms to allow level translator to settle
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
#endif

    // Reset Broadsheet
    einkfb_debug("Sending RST signal to Broadsheet...\n");
    WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_RESET_VAL);     // Assert RST
    mdelay(100);    // Pause 100 ms during reset
    WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_NON_RESET_VAL); // Clear RST
    mdelay(400);    // Pause 400 ms to allow Broasheet time to come up
    einkfb_debug("Broadsheet reset done.\n");

#ifdef TEST_BROADSHEET
    test_broadsheet(disp);
#endif

#ifdef USE_BS_IRQ
    // Set up Broadsheet for interrupt generation (enable all conditions)
    bs_cmd_wr_reg(BS_INTR_CTL_REG, BS_ALL_IRQS);
    bs_cmd_wr_reg(BS_INTR_RAW_STATUS_REG, BS_ALL_IRQS);

    // Enable all Broadsheet display engine interrupts
    bs_cmd_wr_reg(BS_DE_INTR_ENABLE_REG, BS_DE_ALL_IRQS);
    bs_cmd_wr_reg(BS_DE_INTR_RAW_STATUS_REG, BS_DE_ALL_IRQS);
#endif

    einkfb_debug("GPIOs and IRQ set; Broadsheet has been reset\n");
    
    return ( result );
}