| /* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| */ |
| |
| #ifdef CONFIG_SPI_QUP |
| #include <linux/spi/spi.h> |
| #endif |
| #include <linux/leds.h> |
| #include "msm_fb.h" |
| #include "mipi_dsi.h" |
| #include "mipi_novatek.h" |
| #include "mdp4.h" |
| |
| |
| static struct mipi_dsi_panel_platform_data *mipi_novatek_pdata; |
| |
| static struct dsi_buf novatek_tx_buf; |
| static struct dsi_buf novatek_rx_buf; |
| static int mipi_novatek_lcd_init(void); |
| |
| static int wled_trigger_initialized; |
| |
| #define MIPI_DSI_NOVATEK_SPI_DEVICE_NAME "dsi_novatek_3d_panel_spi" |
| #define HPCI_FPGA_READ_CMD 0x84 |
| #define HPCI_FPGA_WRITE_CMD 0x04 |
| |
| #ifdef CONFIG_SPI_QUP |
| static struct spi_device *panel_3d_spi_client; |
| |
| static void novatek_fpga_write(uint8 addr, uint16 value) |
| { |
| char tx_buf[32]; |
| int rc; |
| struct spi_message m; |
| struct spi_transfer t; |
| u8 data[4] = {0x0, 0x0, 0x0, 0x0}; |
| |
| if (!panel_3d_spi_client) { |
| pr_err("%s panel_3d_spi_client is NULL\n", __func__); |
| return; |
| } |
| data[0] = HPCI_FPGA_WRITE_CMD; |
| data[1] = addr; |
| data[2] = ((value >> 8) & 0xFF); |
| data[3] = (value & 0xFF); |
| |
| memset(&t, 0, sizeof t); |
| memset(tx_buf, 0, sizeof tx_buf); |
| t.tx_buf = data; |
| t.len = 4; |
| spi_setup(panel_3d_spi_client); |
| spi_message_init(&m); |
| spi_message_add_tail(&t, &m); |
| |
| rc = spi_sync(panel_3d_spi_client, &m); |
| if (rc) |
| pr_err("%s: SPI transfer failed\n", __func__); |
| |
| return; |
| } |
| |
| static void novatek_fpga_read(uint8 addr) |
| { |
| char tx_buf[32]; |
| int rc; |
| struct spi_message m; |
| struct spi_transfer t; |
| struct spi_transfer rx; |
| char rx_value[2]; |
| u8 data[4] = {0x0, 0x0}; |
| |
| if (!panel_3d_spi_client) { |
| pr_err("%s panel_3d_spi_client is NULL\n", __func__); |
| return; |
| } |
| |
| data[0] = HPCI_FPGA_READ_CMD; |
| data[1] = addr; |
| |
| memset(&t, 0, sizeof t); |
| memset(tx_buf, 0, sizeof tx_buf); |
| memset(&rx, 0, sizeof rx); |
| memset(rx_value, 0, sizeof rx_value); |
| t.tx_buf = data; |
| t.len = 2; |
| rx.rx_buf = rx_value; |
| rx.len = 2; |
| spi_setup(panel_3d_spi_client); |
| spi_message_init(&m); |
| spi_message_add_tail(&t, &m); |
| spi_message_add_tail(&rx, &m); |
| |
| rc = spi_sync(panel_3d_spi_client, &m); |
| if (rc) |
| pr_err("%s: SPI transfer failed\n", __func__); |
| else |
| pr_info("%s: rx_value = 0x%x, 0x%x\n", __func__, |
| rx_value[0], rx_value[1]); |
| |
| return; |
| } |
| |
| static int __devinit panel_3d_spi_probe(struct spi_device *spi) |
| { |
| panel_3d_spi_client = spi; |
| return 0; |
| } |
| static int __devexit panel_3d_spi_remove(struct spi_device *spi) |
| { |
| panel_3d_spi_client = NULL; |
| return 0; |
| } |
| static struct spi_driver panel_3d_spi_driver = { |
| .probe = panel_3d_spi_probe, |
| .remove = __devexit_p(panel_3d_spi_remove), |
| .driver = { |
| .name = "dsi_novatek_3d_panel_spi", |
| .owner = THIS_MODULE, |
| } |
| }; |
| |
| #else |
| |
| static void novatek_fpga_write(uint8 addr, uint16 value) |
| { |
| return; |
| } |
| |
| static void novatek_fpga_read(uint8 addr) |
| { |
| return; |
| } |
| |
| #endif |
| |
| |
| /* novatek blue panel */ |
| |
| #ifdef NOVETAK_COMMANDS_UNUSED |
| static char display_config_cmd_mode1[] = { |
| /* TYPE_DCS_LWRITE */ |
| 0x2A, 0x00, 0x00, 0x01, |
| 0x3F, 0xFF, 0xFF, 0xFF |
| }; |
| |
| static char display_config_cmd_mode2[] = { |
| /* DTYPE_DCS_LWRITE */ |
| 0x2B, 0x00, 0x00, 0x01, |
| 0xDF, 0xFF, 0xFF, 0xFF |
| }; |
| |
| static char display_config_cmd_mode3_666[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0x3A, 0x66, 0x15, 0x80 /* 666 Packed (18-bits) */ |
| }; |
| |
| static char display_config_cmd_mode3_565[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0x3A, 0x55, 0x15, 0x80 /* 565 mode */ |
| }; |
| |
| static char display_config_321[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0x66, 0x2e, 0x15, 0x00 /* Reg 0x66 : 2E */ |
| }; |
| |
| static char display_config_323[] = { |
| /* DTYPE_DCS_WRITE */ |
| 0x13, 0x00, 0x05, 0x00 /* Reg 0x13 < Set for Normal Mode> */ |
| }; |
| |
| static char display_config_2lan[] = { |
| /* DTYPE_DCS_WRITE */ |
| 0x61, 0x01, 0x02, 0xff /* Reg 0x61 : 01,02 < Set for 2 Data Lane > */ |
| }; |
| |
| static char display_config_exit_sleep[] = { |
| /* DTYPE_DCS_WRITE */ |
| 0x11, 0x00, 0x05, 0x80 /* Reg 0x11 < exit sleep mode> */ |
| }; |
| |
| static char display_config_TE_ON[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0x35, 0x00, 0x15, 0x80 |
| }; |
| |
| static char display_config_39H[] = { |
| /* DTYPE_DCS_WRITE */ |
| 0x39, 0x00, 0x05, 0x80 |
| }; |
| |
| static char display_config_set_tear_scanline[] = { |
| /* DTYPE_DCS_LWRITE */ |
| 0x44, 0x00, 0x00, 0xff |
| }; |
| |
| static char display_config_set_twolane[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0xae, 0x03, 0x15, 0x80 |
| }; |
| |
| static char display_config_set_threelane[] = { |
| /* DTYPE_DCS_WRITE1 */ |
| 0xae, 0x05, 0x15, 0x80 |
| }; |
| |
| #else |
| |
| static char sw_reset[2] = {0x01, 0x00}; /* DTYPE_DCS_WRITE */ |
| static char enter_sleep[2] = {0x10, 0x00}; /* DTYPE_DCS_WRITE */ |
| static char exit_sleep[2] = {0x11, 0x00}; /* DTYPE_DCS_WRITE */ |
| static char display_off[2] = {0x28, 0x00}; /* DTYPE_DCS_WRITE */ |
| static char display_on[2] = {0x29, 0x00}; /* DTYPE_DCS_WRITE */ |
| |
| |
| |
| static char rgb_888[2] = {0x3A, 0x77}; /* DTYPE_DCS_WRITE1 */ |
| |
| #if defined(NOVATEK_TWO_LANE) |
| static char set_num_of_lanes[2] = {0xae, 0x03}; /* DTYPE_DCS_WRITE1 */ |
| #else /* 1 lane */ |
| static char set_num_of_lanes[2] = {0xae, 0x01}; /* DTYPE_DCS_WRITE1 */ |
| #endif |
| /* commands by Novatke */ |
| static char novatek_f4[2] = {0xf4, 0x55}; /* DTYPE_DCS_WRITE1 */ |
| static char novatek_8c[16] = { /* DTYPE_DCS_LWRITE */ |
| 0x8C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x08, 0x08, 0x00, 0x30, 0xC0, 0xB7, 0x37}; |
| static char novatek_ff[2] = {0xff, 0x55 }; /* DTYPE_DCS_WRITE1 */ |
| |
| static char set_width[5] = { /* DTYPE_DCS_LWRITE */ |
| 0x2A, 0x00, 0x00, 0x02, 0x1B}; /* 540 - 1 */ |
| static char set_height[5] = { /* DTYPE_DCS_LWRITE */ |
| 0x2B, 0x00, 0x00, 0x03, 0xBF}; /* 960 - 1 */ |
| #endif |
| |
| static char led_pwm2[2] = {0x53, 0x24}; /* DTYPE_DCS_WRITE1 */ |
| static char led_pwm3[2] = {0x55, 0x00}; /* DTYPE_DCS_WRITE1 */ |
| |
| static struct dsi_cmd_desc novatek_video_on_cmds[] = { |
| {DTYPE_DCS_WRITE, 1, 0, 0, 50, |
| sizeof(sw_reset), sw_reset}, |
| {DTYPE_DCS_WRITE, 1, 0, 0, 10, |
| sizeof(exit_sleep), exit_sleep}, |
| {DTYPE_DCS_WRITE, 1, 0, 0, 10, |
| sizeof(display_on), display_on}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(set_num_of_lanes), set_num_of_lanes}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(rgb_888), rgb_888}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(led_pwm2), led_pwm2}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(led_pwm3), led_pwm3}, |
| }; |
| |
| static struct dsi_cmd_desc novatek_cmd_on_cmds[] = { |
| {DTYPE_DCS_WRITE, 1, 0, 0, 50, |
| sizeof(sw_reset), sw_reset}, |
| {DTYPE_DCS_WRITE, 1, 0, 0, 10, |
| sizeof(exit_sleep), exit_sleep}, |
| {DTYPE_DCS_WRITE, 1, 0, 0, 10, |
| sizeof(display_on), display_on}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 50, |
| sizeof(novatek_f4), novatek_f4}, |
| {DTYPE_DCS_LWRITE, 1, 0, 0, 50, |
| sizeof(novatek_8c), novatek_8c}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 50, |
| sizeof(novatek_ff), novatek_ff}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(set_num_of_lanes), set_num_of_lanes}, |
| {DTYPE_DCS_LWRITE, 1, 0, 0, 50, |
| sizeof(set_width), set_width}, |
| {DTYPE_DCS_LWRITE, 1, 0, 0, 50, |
| sizeof(set_height), set_height}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 10, |
| sizeof(rgb_888), rgb_888}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 1, |
| sizeof(led_pwm2), led_pwm2}, |
| {DTYPE_DCS_WRITE1, 1, 0, 0, 1, |
| sizeof(led_pwm3), led_pwm3}, |
| }; |
| |
| static struct dsi_cmd_desc novatek_display_off_cmds[] = { |
| {DTYPE_DCS_WRITE, 1, 0, 0, 10, |
| sizeof(display_off), display_off}, |
| {DTYPE_DCS_WRITE, 1, 0, 0, 120, |
| sizeof(enter_sleep), enter_sleep} |
| }; |
| |
| static char manufacture_id[2] = {0x04, 0x00}; /* DTYPE_DCS_READ */ |
| |
| static struct dsi_cmd_desc novatek_manufacture_id_cmd = { |
| DTYPE_DCS_READ, 1, 0, 1, 5, sizeof(manufacture_id), manufacture_id}; |
| |
| static uint32 mipi_novatek_manufacture_id(struct msm_fb_data_type *mfd) |
| { |
| struct dsi_buf *rp, *tp; |
| struct dsi_cmd_desc *cmd; |
| uint32 *lp; |
| |
| tp = &novatek_tx_buf; |
| rp = &novatek_rx_buf; |
| cmd = &novatek_manufacture_id_cmd; |
| mipi_dsi_cmds_rx(mfd, tp, rp, cmd, 3); |
| lp = (uint32 *)rp->data; |
| pr_info("%s: manufacture_id=%x\n", __func__, *lp); |
| return *lp; |
| } |
| |
| static int fpga_addr; |
| static int fpga_access_mode; |
| static bool support_3d; |
| |
| static void mipi_novatek_3d_init(int addr, int mode) |
| { |
| fpga_addr = addr; |
| fpga_access_mode = mode; |
| } |
| |
| static void mipi_dsi_enable_3d_barrier(int mode) |
| { |
| void __iomem *fpga_ptr; |
| uint32_t ptr_value = 0; |
| |
| if (!fpga_addr && support_3d) { |
| pr_err("%s: fpga_addr not set. Failed to enable 3D barrier\n", |
| __func__); |
| return; |
| } |
| |
| if (fpga_access_mode == FPGA_SPI_INTF) { |
| if (mode == LANDSCAPE) |
| novatek_fpga_write(fpga_addr, 1); |
| else if (mode == PORTRAIT) |
| novatek_fpga_write(fpga_addr, 3); |
| else |
| novatek_fpga_write(fpga_addr, 0); |
| |
| mb(); |
| novatek_fpga_read(fpga_addr); |
| } else if (fpga_access_mode == FPGA_EBI2_INTF) { |
| fpga_ptr = ioremap_nocache(fpga_addr, sizeof(uint32_t)); |
| if (!fpga_ptr) { |
| pr_err("%s: FPGA ioremap failed." |
| "Failed to enable 3D barrier\n", |
| __func__); |
| return; |
| } |
| |
| ptr_value = readl_relaxed(fpga_ptr); |
| if (mode == LANDSCAPE) |
| writel_relaxed(((0xFFFF0000 & ptr_value) | 1), |
| fpga_ptr); |
| else if (mode == PORTRAIT) |
| writel_relaxed(((0xFFFF0000 & ptr_value) | 3), |
| fpga_ptr); |
| else |
| writel_relaxed((0xFFFF0000 & ptr_value), |
| fpga_ptr); |
| |
| mb(); |
| iounmap(fpga_ptr); |
| } else |
| pr_err("%s: 3D barrier not configured correctly\n", |
| __func__); |
| } |
| |
| static int mipi_novatek_lcd_on(struct platform_device *pdev) |
| { |
| struct msm_fb_data_type *mfd; |
| struct mipi_panel_info *mipi; |
| struct msm_panel_info *pinfo; |
| |
| mfd = platform_get_drvdata(pdev); |
| if (!mfd) |
| return -ENODEV; |
| if (mfd->key != MFD_KEY) |
| return -EINVAL; |
| |
| pinfo = &mfd->panel_info; |
| if (pinfo->is_3d_panel) |
| support_3d = TRUE; |
| |
| mipi = &mfd->panel_info.mipi; |
| |
| if (mipi_dsi_ctrl_lock(0)) { |
| if (mipi->mode == DSI_VIDEO_MODE) { |
| mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_video_on_cmds, |
| ARRAY_SIZE(novatek_video_on_cmds)); |
| } else { |
| mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_cmd_on_cmds, |
| ARRAY_SIZE(novatek_cmd_on_cmds)); |
| |
| /* clean up ack_err_status */ |
| mipi_dsi_cmd_bta_sw_trigger(); |
| mipi_novatek_manufacture_id(mfd); |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int mipi_novatek_lcd_off(struct platform_device *pdev) |
| { |
| struct msm_fb_data_type *mfd; |
| |
| mfd = platform_get_drvdata(pdev); |
| |
| if (!mfd) |
| return -ENODEV; |
| if (mfd->key != MFD_KEY) |
| return -EINVAL; |
| |
| if (mipi_dsi_ctrl_lock(0)) { |
| mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_display_off_cmds, |
| ARRAY_SIZE(novatek_display_off_cmds)); |
| } |
| |
| return 0; |
| } |
| |
| DEFINE_LED_TRIGGER(bkl_led_trigger); |
| |
| #ifdef CONFIG_FB_MSM_MDP303 |
| void mdp4_backlight_put_level(int cndx, int level) |
| { |
| /* do nothing */ |
| } |
| #endif |
| |
| static void mipi_novatek_set_backlight(struct msm_fb_data_type *mfd) |
| { |
| struct mipi_panel_info *mipi; |
| |
| if ((mipi_novatek_pdata->enable_wled_bl_ctrl) |
| && (wled_trigger_initialized)) { |
| led_trigger_event(bkl_led_trigger, mfd->bl_level); |
| return; |
| } |
| mipi = &mfd->panel_info.mipi; |
| |
| mdp4_backlight_put_level(0, mfd->bl_level); |
| } |
| |
| static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev); |
| static int barrier_mode; |
| |
| static int __devinit mipi_novatek_lcd_probe(struct platform_device *pdev) |
| { |
| struct msm_fb_data_type *mfd; |
| struct mipi_panel_info *mipi; |
| struct platform_device *current_pdev; |
| static struct mipi_dsi_phy_ctrl *phy_settings; |
| static char dlane_swap; |
| |
| if (pdev->id == 0) { |
| mipi_novatek_pdata = pdev->dev.platform_data; |
| |
| if (mipi_novatek_pdata |
| && mipi_novatek_pdata->phy_ctrl_settings) { |
| phy_settings = (mipi_novatek_pdata->phy_ctrl_settings); |
| } |
| |
| if (mipi_novatek_pdata |
| && mipi_novatek_pdata->dlane_swap) { |
| dlane_swap = (mipi_novatek_pdata->dlane_swap); |
| } |
| |
| if (mipi_novatek_pdata |
| && mipi_novatek_pdata->fpga_3d_config_addr) |
| mipi_novatek_3d_init(mipi_novatek_pdata |
| ->fpga_3d_config_addr, mipi_novatek_pdata->fpga_ctrl_mode); |
| |
| /* create sysfs to control 3D barrier for the Sharp panel */ |
| if (mipi_dsi_3d_barrier_sysfs_register(&pdev->dev)) { |
| pr_err("%s: Failed to register 3d Barrier sysfs\n", |
| __func__); |
| return -ENODEV; |
| } |
| barrier_mode = 0; |
| |
| return 0; |
| } |
| |
| current_pdev = msm_fb_add_device(pdev); |
| |
| if (current_pdev) { |
| mfd = platform_get_drvdata(current_pdev); |
| if (!mfd) |
| return -ENODEV; |
| if (mfd->key != MFD_KEY) |
| return -EINVAL; |
| |
| mipi = &mfd->panel_info.mipi; |
| |
| if (phy_settings != NULL) |
| mipi->dsi_phy_db = phy_settings; |
| |
| if (dlane_swap) |
| mipi->dlane_swap = dlane_swap; |
| } |
| return 0; |
| } |
| |
| static struct platform_driver this_driver = { |
| .probe = mipi_novatek_lcd_probe, |
| .driver = { |
| .name = "mipi_novatek", |
| }, |
| }; |
| |
| static struct msm_fb_panel_data novatek_panel_data = { |
| .on = mipi_novatek_lcd_on, |
| .off = mipi_novatek_lcd_off, |
| .set_backlight = mipi_novatek_set_backlight, |
| }; |
| |
| static ssize_t mipi_dsi_3d_barrier_read(struct device *dev, |
| struct device_attribute *attr, |
| char *buf) |
| { |
| return snprintf((char *)buf, sizeof(buf), "%u\n", barrier_mode); |
| } |
| |
| static ssize_t mipi_dsi_3d_barrier_write(struct device *dev, |
| struct device_attribute *attr, |
| const char *buf, |
| size_t count) |
| { |
| int ret = -1; |
| u32 data = 0; |
| |
| if (sscanf((char *)buf, "%u", &data) != 1) { |
| dev_err(dev, "%s\n", __func__); |
| ret = -EINVAL; |
| } else { |
| barrier_mode = data; |
| if (data == 1) |
| mipi_dsi_enable_3d_barrier(LANDSCAPE); |
| else if (data == 2) |
| mipi_dsi_enable_3d_barrier(PORTRAIT); |
| else |
| mipi_dsi_enable_3d_barrier(0); |
| } |
| |
| return count; |
| } |
| |
| static struct device_attribute mipi_dsi_3d_barrier_attributes[] = { |
| __ATTR(enable_3d_barrier, 0664, mipi_dsi_3d_barrier_read, |
| mipi_dsi_3d_barrier_write), |
| }; |
| |
| static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev) |
| { |
| int i; |
| |
| for (i = 0; i < ARRAY_SIZE(mipi_dsi_3d_barrier_attributes); i++) |
| if (device_create_file(dev, mipi_dsi_3d_barrier_attributes + i)) |
| goto error; |
| |
| return 0; |
| |
| error: |
| for (; i >= 0 ; i--) |
| device_remove_file(dev, mipi_dsi_3d_barrier_attributes + i); |
| pr_err("%s: Unable to create interface\n", __func__); |
| |
| return -ENODEV; |
| } |
| |
| static int ch_used[3]; |
| |
| int mipi_novatek_device_register(struct msm_panel_info *pinfo, |
| u32 channel, u32 panel) |
| { |
| struct platform_device *pdev = NULL; |
| int ret; |
| |
| if ((channel >= 3) || ch_used[channel]) |
| return -ENODEV; |
| |
| ch_used[channel] = TRUE; |
| |
| ret = mipi_novatek_lcd_init(); |
| if (ret) { |
| pr_err("mipi_novatek_lcd_init() failed with ret %u\n", ret); |
| return ret; |
| } |
| |
| pdev = platform_device_alloc("mipi_novatek", (panel << 8)|channel); |
| if (!pdev) |
| return -ENOMEM; |
| |
| novatek_panel_data.panel_info = *pinfo; |
| |
| ret = platform_device_add_data(pdev, &novatek_panel_data, |
| sizeof(novatek_panel_data)); |
| if (ret) { |
| printk(KERN_ERR |
| "%s: platform_device_add_data failed!\n", __func__); |
| goto err_device_put; |
| } |
| |
| ret = platform_device_add(pdev); |
| if (ret) { |
| printk(KERN_ERR |
| "%s: platform_device_register failed!\n", __func__); |
| goto err_device_put; |
| } |
| |
| return 0; |
| |
| err_device_put: |
| platform_device_put(pdev); |
| return ret; |
| } |
| |
| static int mipi_novatek_lcd_init(void) |
| { |
| #ifdef CONFIG_SPI_QUP |
| int ret; |
| ret = spi_register_driver(&panel_3d_spi_driver); |
| |
| if (ret) { |
| pr_err("%s: spi register failed: rc=%d\n", __func__, ret); |
| platform_driver_unregister(&this_driver); |
| } else |
| pr_info("%s: SUCCESS (SPI)\n", __func__); |
| #endif |
| |
| led_trigger_register_simple("bkl_trigger", &bkl_led_trigger); |
| pr_info("%s: SUCCESS (WLED TRIGGER)\n", __func__); |
| wled_trigger_initialized = 1; |
| |
| mipi_dsi_buf_alloc(&novatek_tx_buf, DSI_BUF_SIZE); |
| mipi_dsi_buf_alloc(&novatek_rx_buf, DSI_BUF_SIZE); |
| |
| return platform_driver_register(&this_driver); |
| } |