Exemple #1
0
static int flexfb_verify_gpios_db(struct fbtft_par *par)
{
    int i;
    int num_db = buswidth;

    fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par->info->device, "%s()\n", __func__);

    if (par->gpio.dc < 0) {
        dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
        return -EINVAL;
    }
    if (par->gpio.wr < 0) {
        dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n");
        return -EINVAL;
    }
    if (latched && (par->gpio.latch < 0)) {
        dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n");
        return -EINVAL;
    }
    if (latched)
        num_db=buswidth/2;
    for (i=0; i < num_db; i++) {
        if (par->gpio.db[i] < 0) {
            dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i);
            return -EINVAL;
        }
    }

    return 0;
}
Exemple #2
0
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
	unsigned long mask[] = { 0b11111, 0b11111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, \
	                         0b11111, 0b11111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b111 };
	int i,j;

	fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

	/* apply mask */
	for (i=0;i<2;i++)
		for (j=0;j<10;j++)
			CURVE(i,j) &= mask[i*par->gamma.num_values + j];

	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4) );
	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6) );
	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8) );
	write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2) );
	write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0) );

	write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4) );
	write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6) );
	write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8) );
	write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2) );
	write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0) );

	return 0;
}
Exemple #3
0
/* ili9320, ili9325 */
static void flexfb_set_addr_win_1(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
    fbtft_dev_dbg(DEBUG_SET_ADDR_WIN, par->info->device, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
    switch (par->info->var.rotate) {
    /* R20h = Horizontal GRAM Start Address */
    /* R21h = Vertical GRAM Start Address */
    case 0:
        write_reg(par, 0x0020, xs);
        write_reg(par, 0x0021, ys);
        break;
    case 2:
        write_reg(par, 0x0020, width - 1 - xs);
        write_reg(par, 0x0021, height - 1 - ys);
        break;
    case 1:
        write_reg(par, 0x0020, width - 1 - ys);
        write_reg(par, 0x0021, xs);
        break;
    case 3:
        write_reg(par, 0x0020, ys);
        write_reg(par, 0x0021, height - 1 - xs);
        break;
    }
    write_reg(par, 0x0022); /* Write Data to GRAM */
}
Exemple #4
0
/* ssd1289 */
static void flexfb_set_addr_win_2(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
    fbtft_dev_dbg(DEBUG_SET_ADDR_WIN, par->info->device, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);

    switch (par->info->var.rotate) {
    /* R4Eh - Set GDDRAM X address counter */
    /* R4Fh - Set GDDRAM Y address counter */
    case 0:
        write_reg(par, 0x4e, xs);
        write_reg(par, 0x4f, ys);
        break;
    case 2:
        write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
        write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
        break;
    case 1:
        write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
        write_reg(par, 0x4f, xs);
        break;
    case 3:
        write_reg(par, 0x4e, ys);
        write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
        break;
    }

    /* R22h - RAM data write */
    write_reg(par, 0x22, 0);
}
Exemple #5
0
void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
{
    struct fbtft_par *par = info->par;
    unsigned dirty_lines_start, dirty_lines_end;
    struct page *page;
    unsigned long index;
    unsigned y_low = 0, y_high = 0;
    int count = 0;

    spin_lock(&par->dirty_lock);
    dirty_lines_start = par->dirty_lines_start;
    dirty_lines_end = par->dirty_lines_end;
    /* set display line markers as clean */
    par->dirty_lines_start = par->info->var.yres - 1;
    par->dirty_lines_end = 0;
    spin_unlock(&par->dirty_lock);

    /* Mark display lines as dirty */
    list_for_each_entry(page, pagelist, lru) {
        count++;
        index = page->index << PAGE_SHIFT;
        y_low = index / info->fix.line_length;
        y_high = (index + PAGE_SIZE - 1) / info->fix.line_length;
        fbtft_dev_dbg(DEBUG_DEFERRED_IO, par, info->device,
                      "page->index=%lu y_low=%d y_high=%d\n",
                      page->index, y_low, y_high);
        if (y_high > info->var.yres - 1)
            y_high = info->var.yres - 1;
        if (y_low < dirty_lines_start)
            dirty_lines_start = y_low;
        if (y_high > dirty_lines_end)
            dirty_lines_end = y_high;
    }
Exemple #6
0
static int sainsmart18fb_probe(struct spi_device *spi)
{
	struct fb_info *info;
	struct fbtft_par *par;
	int ret;

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

	info = fbtft_framebuffer_alloc(&sainsmart18_display, &spi->dev);
	if (!info)
		return -ENOMEM;

	par = info->par;
	par->spi = spi;
	fbtft_debug_init(par);
	par->fbtftops.init_display = sainsmart18fb_init_display;
	par->fbtftops.verify_gpios = sainsmart18fb_verify_gpios;
	par->fbtftops.register_backlight = fbtft_register_backlight;

	ret = fbtft_register_framebuffer(info);
	if (ret < 0)
		goto out_release;

	return 0;

out_release:
	fbtft_framebuffer_release(info);

	return ret;
}
Exemple #7
0
static int ssd1351fb_probe(struct spi_device *spi)
{
	struct fb_info *info;
	struct fbtft_par *par;
	int ret;

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

	info = fbtft_framebuffer_alloc(&ssd1351fb_display, &spi->dev);

	if (!info) return -ENOMEM;

	par = info->par;
	par->spi = spi;

	fbtft_debug_init(par);

	par->fbtftops.init_display  = ssd1351fb_init_display;
	par->fbtftops.set_addr_win  = ssd1351fb_set_addr_win;
	par->fbtftops.verify_gpios  = ssd1351fb_verify_gpios;
	par->fbtftops.blank = blank;
	par->fbtftops.set_gamma = set_gamma;

	ret = fbtft_register_framebuffer(info);

	if (ret >= 0) return 0;

	fbtft_framebuffer_release(info);

	return ret;
}
Exemple #8
0
void ili9341fb_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
    uint8_t xsl, xsh, xel, xeh, ysl, ysh, yel, yeh;
    u16 *p = (u16 *)par->buf;
    int i = 0;

    fbtft_dev_dbg(DEBUG_SET_ADDR_WIN, par->info->device, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);

    xsl = (uint8_t)(xs & 0xff);
    xsh = (uint8_t)((xs >> 8) & 0xff);
    xel = (uint8_t)(xe & 0xff);
    xeh = (uint8_t)((xe >> 8) & 0xff);

    ysl = (uint8_t)(ys & 0xff);
    ysh = (uint8_t)((ys >> 8) & 0xff);
    yel = (uint8_t)(ye & 0xff);
    yeh = (uint8_t)((ye >> 8) & 0xff);

    write_cmd(par, FBTFT_CASET);
    write_data(par, xsh);
    write_data(par, xsl);
    write_data(par, xeh);
    write_data(par, xel);

    write_cmd(par, FBTFT_RASET);
    write_data(par, ysh);
    write_data(par, ysl);
    write_data(par, yeh);
    write_data(par, yel);

    write_cmd(par, FBTFT_RAMWR);

    write_flush(par);
}
Exemple #9
0
/*
	Grayscale Lookup Table
	GS1 - GS63
	The "Gamma curve" contains the relative values between the entries in the Lookup table.

	From datasheet:
	The next 63 data bytes define Gray Scale (GS) Table by 
	setting the gray scale pulse width in unit of DCLK's 
	(ranges from 0d ~ 180d) 

	0 = Setting of GS1 < Setting of GS2 < Setting of GS3..... < Setting of GS62 < Setting of GS63

*/
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
	int i, acc = 0;

	fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

	/* verify lookup table */
	for (i=0;i<63;i++) {
		acc += curves[i];
		if (acc > 180) {
			dev_err(par->info->device, "Illegal value(s) in Grayscale Lookup Table. At index=%d, the accumulated value has exceeded 180\n", i);
			return -EINVAL;
		}
		if (curves[i] == 0) {
			dev_err(par->info->device, "Illegal value in Grayscale Lookup Table. Value can't be zero\n");
			return -EINVAL;
		}
	}

	acc = 0;
	write_cmd(par, 0xB8);
	for (i=0;i<63;i++) {
		acc += curves[i];
		write_data(par, acc);
	}

	return 0;
}
Exemple #10
0
static int itdb28fb_remove_pdev(struct platform_device *pdev)
{
	struct fb_info *info = platform_get_drvdata(pdev);

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &pdev->dev, "%s()\n", __func__);
	return itdb28fb_remove_common(&pdev->dev, info);
}
Exemple #11
0
static int itdb28fb_remove_spi(struct spi_device *spi)
{
	struct fb_info *info = spi_get_drvdata(spi);

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);
	return itdb28fb_remove_common(&spi->dev, info);
}
Exemple #12
0
static int itdb28fb_verify_gpios(struct fbtft_par *par)
{
	int i;

	fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par->info->device, "%s()\n", __func__);

	if (par->gpio.dc < 0) {
		dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
		return -EINVAL;
	}
	if (par->pdev) {
		if (par->gpio.wr < 0) {
			dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n");
			return -EINVAL;
		}
		for (i=0;i < 8;i++) {
			if (par->gpio.db[i] < 0) {
				dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i);
				return -EINVAL;
			}
		}
	}

	return 0;
}
Exemple #13
0
static int blank(struct fbtft_par *par, bool on)
{
	fbtft_dev_dbg(DEBUG_BLANK, par->info->device, "%s(blank=%s)\n", __func__, on ? "true" : "false");
	if (on)
		write_cmd(par, 0xAE);
	else
		write_cmd(par, 0xAF);
	return 0;
}
Exemple #14
0
static int nokia3310fb_init_display(struct fbtft_par *par)
{
	u8 contrast = 0x40;  /* between 0x00 and 0x7F */
	u8 tc = 0;           /* Temperature coefficient, between 0 and 3 */
	u8 bias = 4;         /* Bias, between 0 and 7 */

	fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

	par->fbtftops.reset(par);

	/* Function set */
	write_reg(par, 0x21); /* 5:1  1
	                         2:0  PD - Powerdown control: chip is active
							 1:0  V  - Entry mode: horizontal addressing
							 0:1  H  - Extended instruction set control: extended
						  */

	/* H=1 Set Vop (contrast) */
	write_reg(par, 0x80 | contrast); /*
	                         7:1  1
	                         6-0: Vop[6:0] - Operation voltage
	                      */

	/* H=1 Temperature control */
	write_reg(par, 0x04 | tc); /* 
	                         2:1  1
	                         1:x  TC1 - Temperature Coefficient: 0x10
							 0:x  TC0
						  */

	/* H=1 Bias system */
	write_reg(par, 0x10 | bias); /* 
	                         4:1  1
	                         3:0  0
							 2:x  BS2 - Bias System
							 1:x  BS1
							 0:x  BS0
	                      */

	/* Function set */
	write_reg(par, 0x22); /* 5:1  1
	                         2:0  PD - Powerdown control: chip is active
							 1:1  V  - Entry mode: vertical addressing
							 0:0  H  - Extended instruction set control: basic
						  */

	/* H=0 Display control */
	write_reg(par, 0x08 | 4); /* 
	                         3:1  1
	                         2:1  D  - DE: 10=normal mode
							 1:0  0
							 0:0  E
						  */

	return 0;
}
Exemple #15
0
static int nokia3310fb_verify_gpios(struct fbtft_par *par)
{
	fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par->info->device, "%s()\n", __func__);

	if (par->gpio.dc < 0) {
		dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
		return -EINVAL;
	}

	return 0;
}
Exemple #16
0
static int ili9341fb_probe(struct spi_device *spi)
{
    struct fb_info *info;
    struct fbtft_par *par;
    int ret;

    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

    info = fbtft_framebuffer_alloc(&ili9341fb_display, &spi->dev);
    if (!info)
        return -ENOMEM;

    par = info->par;
    par->spi = spi;
    fbtft_debug_init(par);
    par->fbtftops.init_display = ili9341fb_init_display;
    par->fbtftops.register_backlight = fbtft_register_backlight;
    par->fbtftops.request_gpios_match = ili9341fb_request_gpios_match;
    par->fbtftops.write_data_command = fbtft_write_data_command8_bus9;
    par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
    par->fbtftops.set_addr_win = ili9341fb_set_addr_win;

    spi->bits_per_word=9;
    ret = spi->master->setup(spi);
    if (ret) {
        dev_warn(&spi->dev, "9-bit SPI not available, emulating using 8-bit.\n");
        spi->bits_per_word=8;
        ret = spi->master->setup(spi);
        if (ret)
            goto fbreg_fail;

        /* allocate buffer with room for dc bits */
        par->extra = vzalloc(par->txbuf.len + (par->txbuf.len / 8));
        if (!par->extra) {
            ret = -ENOMEM;
            goto fbreg_fail;
        }

        par->fbtftops.write = ili9341fb_write_emulate_9bit;
    }

    ret = fbtft_register_framebuffer(info);
    if (ret < 0)
        goto fbreg_fail;

    return 0;

fbreg_fail:
    if (par->extra)
        vfree(par->extra);
    fbtft_framebuffer_release(info);

    return ret;
}
Exemple #17
0
static int flexfb_remove_common(struct device *dev, struct fb_info *info)
{
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "%s()\n", __func__);

    if (info) {
        fbtft_unregister_framebuffer(info);
        fbtft_framebuffer_release(info);
    }

    return 0;
}
Exemple #18
0
static int sainsmart18fb_remove(struct spi_device *spi)
{
	struct fb_info *info = spi_get_drvdata(spi);

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

	if (info) {
		fbtft_unregister_framebuffer(info);
		fbtft_framebuffer_release(info);
	}

	return 0;
}
Exemple #19
0
static int itdb28fb_remove_common(struct device *dev, struct fb_info *info)
{
	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "%s()\n", __func__);

	if (info) {
		fbtft_unregister_framebuffer(info);
		fbtft_framebuffer_release(info);
	}

	sysfs_remove_group(&dev->kobj, &itdb28fb_attr_group);

	return 0;
}
Exemple #20
0
static int itdb28fb_probe_common(struct spi_device *sdev, struct platform_device *pdev)
{
	struct device *dev;
	struct fb_info *info;
	struct fbtft_par *par;
	int ret;

	if (sdev)
		dev = &sdev->dev;
	else
		dev = &pdev->dev;

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "%s()\n", __func__);

	info = fbtft_framebuffer_alloc(&itdb28fb_display, dev);
	if (!info)
		return -ENOMEM;

	par = info->par;
	if (sdev)
		par->spi = sdev;
	else
		par->pdev = pdev;

	fbtft_debug_init(par);
	par->fbtftops.init_display = itdb28fb_init_display;
	par->fbtftops.set_gamma = set_gamma;
	par->fbtftops.register_backlight = fbtft_register_backlight;
	par->fbtftops.write_reg = fbtft_write_reg16_bus8;
	par->fbtftops.set_addr_win = itdb28fb_set_addr_win;
	par->fbtftops.verify_gpios = itdb28fb_verify_gpios;
	if (pdev)
		par->fbtftops.write = fbtft_write_gpio8_wr;

	ret = fbtft_register_framebuffer(info);
	if (ret < 0)
		goto out_release;

    ret = sysfs_create_group(&pdev->dev.kobj, &itdb28fb_attr_group);
    if (ret)
		goto out_release;

	dev_set_drvdata(&pdev->dev, par);
	return 0;

out_release:
	fbtft_framebuffer_release(info);
	return ret;
}
Exemple #21
0
static int nokia3310fb_probe(struct spi_device *spi)
{
	struct fb_info *info;
	struct fbtft_par *par;
	int ret;

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

	if (rotate) {
		nokia3310fb_display.width = HEIGHT;
		nokia3310fb_display.height = WIDTH;
	} else {
		nokia3310fb_display.width = WIDTH;
		nokia3310fb_display.height = HEIGHT;
	}

	info = fbtft_framebuffer_alloc(&nokia3310fb_display, &spi->dev);
	if (!info)
		return -ENOMEM;

	info->fix.visual = FB_VISUAL_MONO10;
	info->var.red.offset =     0;
	info->var.red.length =     0;
	info->var.green.offset =   0;
	info->var.green.length =   0;
	info->var.blue.offset =    0;
	info->var.blue.length =    0;

	par = info->par;
	par->spi = spi;
	fbtft_debug_init(par);
	par->fbtftops.write_data_command = fbtft_write_data_command8_bus8;
	par->fbtftops.verify_gpios = nokia3310fb_verify_gpios;
	par->fbtftops.init_display = nokia3310fb_init_display;
	par->fbtftops.register_backlight = fbtft_register_backlight;
	par->fbtftops.update_display = nokia3310fb_update_display;

	ret = fbtft_register_framebuffer(info);
	if (ret < 0)
		goto out_release;

	return 0;

out_release:
	fbtft_framebuffer_release(info);

	return ret;
}
Exemple #22
0
static int ili9341fb_remove(struct spi_device *spi)
{
    struct fb_info *info = spi_get_drvdata(spi);
    struct fbtft_par *par;

    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

    if (info) {
        fbtft_unregister_framebuffer(info);
        par = info->par;
        if (par->extra)
            vfree(par->extra);
        fbtft_framebuffer_release(info);
    }

    return 0;
}
Exemple #23
0
static int nokia3310fb_remove(struct spi_device *spi)
{
	struct fb_info *info = spi_get_drvdata(spi);

	fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, &spi->dev, "%s()\n", __func__);

	if (info) {
		if (info->bl_dev) {
			/* turn off backlight or else it will fade out */
			info->bl_dev->props.power = FB_BLANK_POWERDOWN;
			info->bl_dev->ops->update_status(info->bl_dev);
		}
		fbtft_unregister_framebuffer(info);
		fbtft_framebuffer_release(info);
	}

	return 0;
}
Exemple #24
0
void nokia3310fb_update_display(struct fbtft_par *par)
{
	u8 *vmem8 = vmem8 = par->info->screen_base;
	u8 *buf = par->txbuf.buf;
	int i;
	int ret = 0;

	fbtft_dev_dbg(DEBUG_UPDATE_DISPLAY, par->info->device, "%s()\n", __func__);

	if (par->info->var.xres == WIDTH) {
		/* rearrange */
		for (i=0; i<84; i++) {
			buf[i*6+0] = vmem8[i*6+5];
			buf[i*6+1] = vmem8[i*6+4];
			buf[i*6+2] = vmem8[i*6+3];
			buf[i*6+3] = vmem8[i*6+2];
			buf[i*6+4] = vmem8[i*6+1];
			buf[i*6+5] = vmem8[i*6+0];
		}
	} else {
		/* rearrange and rotate */
		dev_err(par->info->device, "%s: rotation not supported yet\n", __func__);
		return;
	}

	/* H=0 Set X address of RAM */
	write_reg(par, 0x80); /* 7:1  1
	                         6-0: X[6:0] - 0x00
	                      */

	/* H=0 Set Y address of RAM */
	write_reg(par, 0x40); /* 7:0  0
	                         6:1  1
	                         2-0: Y[2:0] - 0x0
	                      */

	/* Write data */
	gpio_set_value(par->gpio.dc, 1);
	ret = par->fbtftops.write(par, buf, par->info->fix.smem_len);
	if (ret < 0)
		dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret);
}
Exemple #25
0
void adafruit22fb_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	u16 *p = (u16 *)par->buf;
	int i = 0;

	fbtft_dev_dbg(DEBUG_SET_ADDR_WIN, par->info->device, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);

	write_cmd(par, FBTFT_CASET);
	write_data(par, 0x00);
	write_data(par, xs);
	write_data(par, 0x00);
	write_data(par, xe);

	write_cmd(par, FBTFT_RASET);
	write_data(par, 0x00);
	write_data(par, ys);
	write_data(par, 0x00);
	write_data(par, ye);

	write_cmd(par, FBTFT_RAMWR);

	write_flush(par);
}
Exemple #26
0
static int flexfb_probe_common(struct spi_device *sdev, struct platform_device *pdev)
{
    struct device *dev;
    struct fb_info *info;
    struct fbtft_par *par;
    int ret;

    initp = init;
    initp_num = init_num;

    if (sdev)
        dev = &sdev->dev;
    else
        dev = &pdev->dev;

    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "%s(%s)\n", __func__, sdev ? "'SPI device'" : "'Platform device'");

    if (chip) {

        if (!strcmp(chip, "st7735r")) {
            if (!width)
                width = 128;
            if (!height)
                height = 160;
            if (init_num == 0) {
                initp = st7735r_init;
                initp_num = ARRAY_SIZE(st7735r_init);
            }


        } else if (!strcmp(chip, "hx8340bn")) {
            if (!width)
                width = 176;
            if (!height)
                height = 220;
            setaddrwin = 0;
            if (init_num == 0) {
                initp = hx8340bn_init;
                initp_num = ARRAY_SIZE(hx8340bn_init);
            }


        } else if (!strcmp(chip, "ili9225")) {
            if (!width)
                width = 176;
            if (!height)
                height = 220;
            setaddrwin = 0;
            regwidth = 16;
            if (init_num == 0) {
                initp = ili9225_init;
                initp_num = ARRAY_SIZE(ili9225_init);
            }



        } else if (!strcmp(chip, "ili9320")) {
            if (!width)
                width = 240;
            if (!height)
                height = 320;
            setaddrwin = 1;
            regwidth = 16;
            if (init_num == 0) {
                initp = ili9320_init;
                initp_num = ARRAY_SIZE(ili9320_init);
            }


        } else if (!strcmp(chip, "ili9325")) {
            if (!width)
                width = 240;
            if (!height)
                height = 320;
            setaddrwin = 1;
            regwidth = 16;
            if (init_num == 0) {
                initp = ili9325_init;
                initp_num = ARRAY_SIZE(ili9325_init);
            }

        } else if (!strcmp(chip, "ili9341")) {
            if (!width)
                width = 240;
            if (!height)
                height = 320;
            setaddrwin = 0;
            regwidth = 8;
            if (init_num == 0) {
                initp = ili9341_init;
                initp_num = ARRAY_SIZE(ili9341_init);
            }


        } else if (!strcmp(chip, "ssd1289")) {
            if (!width)
                width = 240;
            if (!height)
                height = 320;
            setaddrwin = 2;
            regwidth = 16;
            if (init_num == 0) {
                initp = ssd1289_init;
                initp_num = ARRAY_SIZE(ssd1289_init);
            }



        } else if (!strcmp(chip, "ssd1351")) {
            if (!width)
                width = 128;
            if (!height)
                height = 128;
            setaddrwin = 3;
            if (init_num == 0) {
                initp = ssd1351_init;
                initp_num = ARRAY_SIZE(ssd1351_init);
            }
        } else {
            dev_err(dev, "chip=%s is not supported\n", chip);
            return -EINVAL;
        }
    }

    if (width == 0 || height == 0) {
        dev_err(dev, "argument(s) missing: width and height has to be set.\n");
        return -EINVAL;
    }
    flex_display.width = width;
    flex_display.height = height;
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "Display resolution: %dx%d\n", width, height);
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "chip = %s\n", chip ? chip : "not set");
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "setaddrwin = %d\n", setaddrwin);
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "regwidth = %d\n", regwidth);
    fbtft_dev_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, dev, "buswidth = %d\n", buswidth);

    info = fbtft_framebuffer_alloc(&flex_display, dev);
    if (!info)
        return -ENOMEM;

    par = info->par;
    if (sdev)
        par->spi = sdev;
    else
        par->pdev = pdev;
    fbtft_debug_init(par);
    par->fbtftops.init_display = flexfb_init_display;

    /* registerwrite functions */
    switch (regwidth) {
    case 8:
        par->fbtftops.write_reg = fbtft_write_reg8_bus8;
        par->fbtftops.write_data_command = fbtft_write_data_command8_bus8;
        break;
    case 16:
        par->fbtftops.write_reg = fbtft_write_reg16_bus8;
        par->fbtftops.write_data_command = fbtft_write_data_command16_bus8;
        break;
    default:
        dev_err(dev, "argument 'regwidth': %d is not supported.\n", regwidth);
        return -EINVAL;
    }

    /* bus functions */
    if (sdev) {
        switch (buswidth) {
        case 8:
            par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
            if (!par->startbyte)
                par->fbtftops.verify_gpios = flexfb_verify_gpios_dc;
            break;
        case 9:
            if (regwidth == 16) {
                dev_err(dev, "argument 'regwidth': %d is not supported with buswidth=%d and SPI.\n", regwidth, buswidth);
                return -EINVAL;
            }
            par->fbtftops.write_data_command = fbtft_write_data_command8_bus9;
            par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
            sdev->bits_per_word=9;
            ret = sdev->master->setup(sdev);
            if (ret) {
                dev_err(dev, "SPI 9-bit setup failed: %d.\n", ret);
                return ret;
            }
            break;
        default:
            dev_err(dev, "argument 'buswidth': %d is not supported with SPI.\n", buswidth);
            return -EINVAL;
        }
        par->fbtftops.write = fbtft_write_spi;
    } else {
        par->fbtftops.verify_gpios = flexfb_verify_gpios_db;
        switch (buswidth) {
        case 8:
            par->fbtftops.write = fbtft_write_gpio8_wr;
            par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
            break;
        case 16:
            par->fbtftops.write_reg = fbtft_write_reg16_bus16;
            par->fbtftops.write_data_command = fbtft_write_data_command16_bus16;
            if (latched)
                par->fbtftops.write = fbtft_write_gpio16_wr_latched;
            else
                par->fbtftops.write = fbtft_write_gpio16_wr;
            par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
            break;
        default:
            dev_err(dev, "argument 'buswidth': %d is not supported with parallel.\n", buswidth);
            return -EINVAL;
        }
    }

    /* set_addr_win function */
    switch (setaddrwin) {
    case 0:
        /* use default */
        break;
    case 1:
        par->fbtftops.set_addr_win = flexfb_set_addr_win_1;
        break;
    case 2:
        par->fbtftops.set_addr_win = flexfb_set_addr_win_2;
        break;
    case 3:
        par->fbtftops.set_addr_win = set_addr_win_3;
        break;
    default:
        dev_err(dev, "argument 'setaddrwin': unknown value %d.\n", setaddrwin);
        return -EINVAL;
    }

    if (!nobacklight)
        par->fbtftops.register_backlight = fbtft_register_backlight;

    ret = fbtft_register_framebuffer(info);
    if (ret < 0)
        goto out_release;

    return 0;

out_release:
    fbtft_framebuffer_release(info);

    return ret;
}
Exemple #27
0
static int sainsmart18fb_init_display(struct fbtft_par *par)
{
	fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

	par->fbtftops.reset(par);

	/* SWRESET - Software reset */
	write_reg(par, 0x01);
	mdelay(150);

	/* SLPOUT - Sleep out & booster on */
	write_reg(par, 0x11);
	mdelay(500);

	/* FRMCTR1 - frame rate control - normal mode */
	write_reg(par, 0xB1, 0x01, 0x2C, 0x2D); /* frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */

	/* FRMCTR2 - frame rate control - idle mode */
	write_reg(par, 0xB2, 0x01, 0x2C, 0x2D); /* frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */

	/* FRMCTR1 - frame rate control - partial mode */
	write_reg(par, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D); /* dot inversion mode, line inversion mode */

	/* INVCTR - // display inversion control */
	write_reg(par, 0xB4, 0x07);	/* no inversion */

	/* PWCTR1 - Power Control */
	write_reg(par, 0xC0, 0xA2, 0x02, 0x84); /* -4.6V, AUTO mode */

	/* PWCTR2 - Power Control */
	write_reg(par, 0xC1, 0xC5);	/* VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */

	/* PWCTR3 - Power Control */
	write_reg(par, 0xC2, 0x0A, 0x00); /* Opamp current small, Boost frequency */

	/* PWCTR4 - Power Control */
	write_reg(par, 0xC3, 0x8A, 0x2A); /* BCLK/2, Opamp current small & Medium low */

	/* PWCTR5 - Power Control */
	write_reg(par, 0xC4, 0x8A, 0xEE);

	/* VMCTR1 - Power Control */
	write_reg(par, 0xC5, 0x0E);

	/* INVOFF - Display inversion off */
	write_reg(par, 0x20);

	/* MADCTL - Memory data access control */
	/*   Mode selection pin SRGB: RGB direction select H/W pin for color filter setting: 0=RGB, 1=BGR   */
	/*   MADCTL RGB bit: RGB-BGR ORDER: 0=RGB color filter panel, 1=BGR color filter panel              */
	#define MY (1 << 7)
	#define MX (1 << 6)
	#define MV (1 << 5)
	switch (par->info->var.rotate) {
	case 0:
		write_reg(par, 0x36, MX | MY | (par->bgr << 3));
		break;
	case 1:
		write_reg(par, 0x36, MY | MV | (par->bgr << 3));
		break;
	case 2:
		write_reg(par, 0x36, (par->bgr << 3));
		break;
	case 3:
		write_reg(par, 0x36, MX | MV | (par->bgr << 3));
		break;
	}

	/* COLMOD - Interface pixel format */
	write_reg(par, 0x3A, 0x05);

	/* GMCTRP1 - Gamma control */
	write_reg(par, 0xE0, 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10);
/*	write_reg(par, 0xE0, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10); */
  
	/* GMCTRN1 - Gamma control */
	write_reg(par, 0xE1, 0x0f , 0x1b , 0x0f , 0x17 , 0x33 , 0x2c , 0x29 , 0x2e , 0x30 , 0x30 , 0x39 , 0x3f , 0x00 , 0x07 , 0x03 , 0x10); 
/*	write_reg(par, 0xE1, 0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e, 0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10); */

	/* DISPON - Display On */
	write_reg(par, 0x29);
	mdelay(100);

	/* NORON - Partial off (Normal) */
	write_reg(par, 0x13);
	mdelay(10);

	return 0;
}
Exemple #28
0
static int ssd1351fb_init_display(struct fbtft_par *par)
{
	fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

	// Reset the device.
	par->fbtftops.reset(par);

	// Write the init sequence.
	write_cmd(par, 0xfd); // Command Lock
	write_data(par, 0x12);

	write_cmd(par, 0xfd); // Command Lock
	write_data(par, 0xb1);

	write_cmd(par, 0xae); // Display Off

	write_cmd(par, 0xb3); // Front Clock Div
	write_data(par, 0xf1);

	write_cmd(par, 0xca); // Set Mux Ratio
	write_data(par, 0x7f);

	write_cmd(par, 0xa0); // Set Colour Depth
	write_data(par, 0x74); // 0xb4

	write_cmd(par, 0x15); // Set Column Address
	write_data(par, 0x00);
	write_data(par, 0x7f);

	write_cmd(par, 0x75); // Set Row Address
	write_data(par, 0x00);
	write_data(par, 0x7f);

	write_cmd(par, 0xa1); // Set Display Start Line
	write_data(par, 0x00);

	write_cmd(par, 0xa2); // Set Display Offset
	write_data(par, 0x00);

	write_cmd(par, 0xb5); // Set GPIO
	write_data(par, 0x00);

	write_cmd(par, 0xab); // Set Function Selection
	write_data(par, 0x01);

	write_cmd(par, 0xb1); // Set Phase Length
	write_data(par, 0x32);

	write_cmd(par, 0xb4); // Set Segment Low Voltage
	write_data(par, 0xa0);
	write_data(par, 0xb5);
	write_data(par, 0x55);

	write_cmd(par, 0xbb); // Set Precharge Voltage
	write_data(par, 0x17);

	write_cmd(par, 0xbe); // Set VComH Voltage
	write_data(par, 0x05);

	write_cmd(par, 0xc1); // Set Contrast
	write_data(par, 0xc8);
	write_data(par, 0x80);
	write_data(par, 0xc8);

	write_cmd(par, 0xc7); // Set Master Contrast
	write_data(par, 0x0f);

	write_cmd(par, 0xb6); // Set Second Precharge Period
	write_data(par, 0x01);

	write_cmd(par, 0xa6); // Set Display Mode Reset

	write_cmd(par, 0xaf); // Set Sleep Mode Display On

	return 0;
}
Exemple #29
0
static int flexfb_init_display(struct fbtft_par *par)
{
    char msg[128];
    char str[16];
    int i = 0;
    int j;

    fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

    par->fbtftops.reset(par);

    if (par->gpio.cs != -1)
        gpio_set_value(par->gpio.cs, 0);  /* Activate chip */

    /* make sure stop marker exists */
    if (initp[initp_num - 1] != -3) {
        dev_err(par->info->device, "argument 'init': missing stop marker (-3) at end of init sequence\n");
        return -1;
    }

    while (i < initp_num) {
        if (initp[i] >= 0) {
            dev_err(par->info->device, "argument 'init': missing delimiter at position %d\n", i);
            return -1;
        }
        if (initp[i] == -3) {
            /* done */
            return 0;
        }
        if ( ((i+1) == initp_num) || (initp[i+1] < 0) ) {
            dev_err(par->info->device, "argument 'init': missing value after delimiter %d at position %d\n", initp[i], i);
            return -1;
        }
        switch (initp[i]) {
        case -1:
            i++;
            /* make debug message */
            strcpy(msg, "");
            j = i + 1;
            while (initp[j] >= 0) {
                sprintf(str, "0x%02X ", initp[j]);
                strcat(msg, str);
                j++;
            }
            fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "init: write(0x%02X) %s\n", initp[i], msg);
            /* Write */
            par->fbtftops.write_data_command(par, 0, initp[i++]);
            while (initp[i] >= 0) {
                par->fbtftops.write_data_command(par, 1, initp[i++]);
            }
            break;
        case -2:
            i++;
            fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "init: mdelay(%d)\n", initp[i]);
            mdelay(initp[i++]);
            break;
        default:
            dev_err(par->info->device, "argument 'init': unknown delimiter %d at position %d\n", initp[i], i);
            return -1;
        }
    }

    dev_err(par->info->device, "%s: something is wrong. Shouldn't get here.\n", __func__);
    return -1;
}
Exemple #30
0
static int ili9341fb_init_display(struct fbtft_par *par)
{
    u16 *p = (u16 *)par->buf;
    int i = 0;

    fbtft_dev_dbg(DEBUG_INIT_DISPLAY, par->info->device, "%s()\n", __func__);

    par->fbtftops.reset(par);

    /* startup sequence for Watterott's MI0283QT9 */

#if 0
    // not needed
    write_cmd(par, LCD_CMD_RESET);
    write_flush(par);
    mdelay(120);
#endif

    write_cmd(par, LCD_CMD_DISPLAY_OFF);
    write_flush(par);
    mdelay(20);

    //send init commands
    write_cmd(par, LCD_CMD_POWER_CTRLB);
    write_data(par, 0x00);
    write_data(par, 0x83); //83 81 AA
    write_data(par, 0x30);

    write_cmd(par, LCD_CMD_POWERON_SEQ_CTRL);
    write_data(par, 0x64); //64 67
    write_data(par, 0x03);
    write_data(par, 0x12);
    write_data(par, 0x81);

    write_cmd(par, LCD_CMD_DRV_TIMING_CTRLA);
    write_data(par, 0x85);
    write_data(par, 0x01);
    write_data(par, 0x79); //79 78

    write_cmd(par, LCD_CMD_POWER_CTRLA);
    write_data(par, 0x39);
    write_data(par, 0X2C);
    write_data(par, 0x00);
    write_data(par, 0x34);
    write_data(par, 0x02);

    write_cmd(par, LCD_CMD_PUMP_RATIO_CTRL);
    write_data(par, 0x20);

    write_cmd(par, LCD_CMD_DRV_TIMING_CTRLB);
    write_data(par, 0x00);
    write_data(par, 0x00);

    write_cmd(par, LCD_CMD_POWER_CTRL1);
    write_data(par, 0x26); //26 25

    write_cmd(par, LCD_CMD_POWER_CTRL2);
    write_data(par, 0x11);

    write_cmd(par, LCD_CMD_VCOM_CTRL1);
    write_data(par, 0x35);
    write_data(par, 0x3E);

    write_cmd(par, LCD_CMD_VCOM_CTRL2);
    write_data(par, 0xBE); //BE 94

    write_cmd(par, LCD_CMD_FRAME_CTRL);
    write_data(par, 0x00);
    write_data(par, 0x1B); //1B 70

    write_cmd(par, LCD_CMD_DISPLAY_CTRL);
    write_data(par, 0x0A);
    write_data(par, 0x82);
    write_data(par, 0x27);
    write_data(par, 0x00);

    write_cmd(par, LCD_CMD_ENTRY_MODE);
    write_data(par, 0x07);

    write_cmd(par, LCD_CMD_PIXEL_FORMAT);
    write_data(par, 0x55); //16bit

    // orientation
    write_cmd(par, LCD_CMD_MEMACCESS_CTRL);
    switch (par->info->var.rotate) {
    case 0:
        write_data(par, (1<<MEM_X) | (!par->bgr << MEM_BGR));
        break;
    case 1:
        write_data(par, (1<<MEM_V) | (1<<MEM_L) | (!par->bgr << MEM_BGR));
        break;
    case 2:
        write_data(par, (1<<MEM_Y) | (!par->bgr << MEM_BGR));
        break;
    case 3:
        write_data(par, (1<<MEM_Y) | (1<<MEM_X)| (1<<MEM_V) | (!par->bgr << MEM_BGR));
        break;
    }

    write_cmd(par, LCD_CMD_SLEEPOUT);
    write_flush(par);
    mdelay(120);

    write_cmd(par, LCD_CMD_DISPLAY_ON);
    write_flush(par);
    mdelay(20);

    return 0;
}