linux/arch/arm/mach-nspire/clcd.c
<<
>>
Prefs
   1/*
   2 *      linux/arch/arm/mach-nspire/clcd.c
   3 *
   4 *      Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2, as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/of.h>
  14#include <linux/amba/bus.h>
  15#include <linux/amba/clcd.h>
  16#include <linux/dma-mapping.h>
  17
  18static struct clcd_panel nspire_cx_lcd_panel = {
  19        .mode           = {
  20                .name           = "Color LCD",
  21                .refresh        = 60,
  22                .xres           = 320,
  23                .yres           = 240,
  24                .sync           = 0,
  25                .vmode          = FB_VMODE_NONINTERLACED,
  26                .pixclock       = 1,
  27                .hsync_len      = 6,
  28                .vsync_len      = 1,
  29                .right_margin   = 50,
  30                .left_margin    = 38,
  31                .lower_margin   = 3,
  32                .upper_margin   = 17,
  33        },
  34        .width          = 65, /* ~6.50 cm */
  35        .height         = 49, /* ~4.87 cm */
  36        .tim2           = TIM2_IPC,
  37        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
  38        .bpp            = 16,
  39        .caps           = CLCD_CAP_565,
  40};
  41
  42static struct clcd_panel nspire_classic_lcd_panel = {
  43        .mode           = {
  44                .name           = "Grayscale LCD",
  45                .refresh        = 60,
  46                .xres           = 320,
  47                .yres           = 240,
  48                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  49                .vmode          = FB_VMODE_NONINTERLACED,
  50                .pixclock       = 1,
  51                .hsync_len      = 6,
  52                .vsync_len      = 1,
  53                .right_margin   = 6,
  54                .left_margin    = 6,
  55        },
  56        .width          = 71, /* 7.11cm */
  57        .height         = 53, /* 5.33cm */
  58        .tim2           = 0x80007d0,
  59        .cntl           = CNTL_LCDMONO8,
  60        .bpp            = 8,
  61        .grayscale      = 1,
  62        .caps           = CLCD_CAP_5551,
  63};
  64
  65int nspire_clcd_setup(struct clcd_fb *fb)
  66{
  67        struct clcd_panel *panel;
  68        size_t panel_size;
  69        const char *type;
  70        dma_addr_t dma;
  71        int err;
  72
  73        BUG_ON(!fb->dev->dev.of_node);
  74
  75        err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
  76        if (err) {
  77                pr_err("CLCD: Could not find lcd-type property\n");
  78                return err;
  79        }
  80
  81        if (!strcmp(type, "cx")) {
  82                panel = &nspire_cx_lcd_panel;
  83        } else if (!strcmp(type, "classic")) {
  84                panel = &nspire_classic_lcd_panel;
  85        } else {
  86                pr_err("CLCD: Unknown lcd-type %s\n", type);
  87                return -EINVAL;
  88        }
  89
  90        panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
  91        panel_size = ALIGN(panel_size, PAGE_SIZE);
  92
  93        fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, panel_size, &dma,
  94                                          GFP_KERNEL);
  95
  96        if (!fb->fb.screen_base) {
  97                pr_err("CLCD: unable to map framebuffer\n");
  98                return -ENOMEM;
  99        }
 100
 101        fb->fb.fix.smem_start = dma;
 102        fb->fb.fix.smem_len = panel_size;
 103        fb->panel = panel;
 104
 105        return 0;
 106}
 107
 108int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 109{
 110        return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
 111                           fb->fb.fix.smem_start, fb->fb.fix.smem_len);
 112}
 113
 114void nspire_clcd_remove(struct clcd_fb *fb)
 115{
 116        dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
 117                    fb->fb.fix.smem_start);
 118}
 119