|
@@ -267,3 +267,121 @@ static int am200_setup_fb(struct metronomefb_par *par)
|
|
|
/* metromem was set up by the notifier in share_video_mem so now
|
|
|
* we can use its value to calculate the other entries */
|
|
|
par->metromem_cmd = (struct metromem_cmd *) am200_board.metromem;
|
|
|
+ par->metromem_wfm = am200_board.metromem + fw;
|
|
|
+ par->metromem_img = par->metromem_wfm + am200_board.wfm_size;
|
|
|
+ par->metromem_img_csum = (u16 *) (par->metromem_img + (fw * fh));
|
|
|
+ par->metromem_dma = am200_board.host_fbinfo->fix.smem_start;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int am200_get_panel_type(void)
|
|
|
+{
|
|
|
+ return panel_type;
|
|
|
+}
|
|
|
+
|
|
|
+static irqreturn_t am200_handle_irq(int irq, void *dev_id)
|
|
|
+{
|
|
|
+ struct metronomefb_par *par = dev_id;
|
|
|
+
|
|
|
+ wake_up_interruptible(&par->waitq);
|
|
|
+ return IRQ_HANDLED;
|
|
|
+}
|
|
|
+
|
|
|
+static int am200_setup_irq(struct fb_info *info)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am200_handle_irq,
|
|
|
+ IRQF_DISABLED|IRQF_TRIGGER_FALLING,
|
|
|
+ "AM200", info->par);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&am200_device->dev, "request_irq failed: %d\n", ret);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void am200_set_rst(struct metronomefb_par *par, int state)
|
|
|
+{
|
|
|
+ gpio_set_value(RST_GPIO_PIN, state);
|
|
|
+}
|
|
|
+
|
|
|
+static void am200_set_stdby(struct metronomefb_par *par, int state)
|
|
|
+{
|
|
|
+ gpio_set_value(STDBY_GPIO_PIN, state);
|
|
|
+}
|
|
|
+
|
|
|
+static int am200_wait_event(struct metronomefb_par *par)
|
|
|
+{
|
|
|
+ return wait_event_timeout(par->waitq, gpio_get_value(RDY_GPIO_PIN), HZ);
|
|
|
+}
|
|
|
+
|
|
|
+static int am200_wait_event_intr(struct metronomefb_par *par)
|
|
|
+{
|
|
|
+ return wait_event_interruptible_timeout(par->waitq,
|
|
|
+ gpio_get_value(RDY_GPIO_PIN), HZ);
|
|
|
+}
|
|
|
+
|
|
|
+static struct metronome_board am200_board = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .setup_irq = am200_setup_irq,
|
|
|
+ .setup_io = am200_init_gpio_regs,
|
|
|
+ .setup_fb = am200_setup_fb,
|
|
|
+ .set_rst = am200_set_rst,
|
|
|
+ .set_stdby = am200_set_stdby,
|
|
|
+ .met_wait_event = am200_wait_event,
|
|
|
+ .met_wait_event_intr = am200_wait_event_intr,
|
|
|
+ .get_panel_type = am200_get_panel_type,
|
|
|
+ .cleanup = am200_cleanup,
|
|
|
+};
|
|
|
+
|
|
|
+static unsigned long am200_pin_config[] __initdata = {
|
|
|
+ GPIO51_GPIO,
|
|
|
+ GPIO49_GPIO,
|
|
|
+ GPIO48_GPIO,
|
|
|
+ GPIO32_GPIO,
|
|
|
+ GPIO17_GPIO,
|
|
|
+ GPIO16_GPIO,
|
|
|
+};
|
|
|
+
|
|
|
+int __init am200_init(void)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* before anything else, we request notification for any fb
|
|
|
+ * creation events */
|
|
|
+ fb_register_client(&am200_fb_notif);
|
|
|
+
|
|
|
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config));
|
|
|
+
|
|
|
+ /* request our platform independent driver */
|
|
|
+ request_module("metronomefb");
|
|
|
+
|
|
|
+ am200_device = platform_device_alloc("metronomefb", -1);
|
|
|
+ if (!am200_device)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ /* the am200_board that will be seen by metronomefb is a copy */
|
|
|
+ platform_device_add_data(am200_device, &am200_board,
|
|
|
+ sizeof(am200_board));
|
|
|
+
|
|
|
+ /* this _add binds metronomefb to am200. metronomefb refcounts am200 */
|
|
|
+ ret = platform_device_add(am200_device);
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ platform_device_put(am200_device);
|
|
|
+ fb_unregister_client(&am200_fb_notif);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ am200_presetup_fb();
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+module_param(panel_type, uint, 0);
|
|
|
+MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
|
|
|
+
|
|
|
+MODULE_DESCRIPTION("board driver for am200 metronome epd kit");
|
|
|
+MODULE_AUTHOR("Jaya Kumar");
|
|
|
+MODULE_LICENSE("GPL");
|