/*
* Epson HWA742 LCD controller driver
*
* Copyright (C) 2004-2005 Nokia Corporation
* Authors: Juha Yrjölä <juha.yrjola@nokia.com>
* Imre Deak <imre.deak@nokia.com>
* YUV support: Jussi Laako <jussi.laako@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include "omapfb.h"
#define HWA742_REV_CODE_REG 0x0
#define HWA742_CONFIG_REG 0x2
#define HWA742_PLL_DIV_REG 0x4
#define HWA742_PLL_0_REG 0x6
#define HWA742_PLL_1_REG 0x8
#define HWA742_PLL_2_REG 0xa
#define HWA742_PLL_3_REG 0xc
#define HWA742_PLL_4_REG 0xe
#define HWA742_CLK_SRC_REG 0x12
#define HWA742_PANEL_TYPE_REG 0x14
#define HWA742_H_DISP_REG 0x16
#define HWA742_H_NDP_REG 0x18
#define HWA742_V_DISP_1_REG 0x1a
#define HWA742_V_DISP_2_REG 0x1c
#define HWA742_V_NDP_REG 0x1e
#define HWA742_HS_W_REG 0x20
#define HWA742_HP_S_REG 0x22
#define HWA742_VS_W_REG 0x24
#define HWA742_VP_S_REG 0x26
#define HWA742_PCLK_POL_REG 0x28
#define HWA742_INPUT_MODE_REG 0x2a
#define HWA742_TRANSL_MODE_REG1 0x2e
#define HWA742_DISP_MODE_REG 0x34
#define HWA742_WINDOW_TYPE 0x36
#define HWA742_WINDOW_X_START_0 0x38
#define HWA742_WINDOW_X_START_1 0x3a
#define HWA742_WINDOW_Y_START_0 0x3c
#define HWA742_WINDOW_Y_START_1 0x3e
#define HWA742_WINDOW_X_END_0 0x40
#define HWA742_WINDOW_X_END_1 0x42
#define HWA742_WINDOW_Y_END_0 0x44
#define HWA742_WINDOW_Y_END_1 0x46
#define HWA742_MEMORY_WRITE_LSB 0x48
#define HWA742_MEMORY_WRITE_MSB 0x49
#define HWA742_MEMORY_READ_0 0x4a
#define HWA742_MEMORY_READ_1 0x4c
#define HWA742_MEMORY_READ_2 0x4e
#define HWA742_POWER_SAVE 0x56
#define HWA742_NDP_CTRL 0x58
#define HWA742_AUTO_UPDATE_TIME (HZ / 20)
/* Reserve 4 request slots for requests in irq context */
#define REQ_POOL_SIZE 24
#define IRQ_REQ_POOL_SIZE 4
#define REQ_FROM_IRQ_POOL 0x01
#define REQ_COMPLETE 0
#define REQ_PENDING 1
struct update_param {
int x, y, width, height;
int color_mode;
int flags;
};
struct hwa742_request {
struct list_head entry;
unsigned int flags;
int (*handler)(struct hwa742_request *req);
void (*complete)(void *data);
void *complete_data;
union {
struct update_param update;
struct completion *sync;
} par;
};
struct {
enum omapfb_update_mode update_mode;
enum omapfb_update_mode update_mode_before_suspend;
struct timer_list auto_update_timer;
int stop_auto_update;
struct omapfb_update_window auto_update_window;
unsigned te_connected:1;
unsigned vsync_only:1;
struct hwa742_request req_pool[REQ_POOL_SIZE];
struct list_head pending_req_list;
struct list_head free_req_list;
struct semaphore req_sema;
spinlock_t req_lock;
struct extif_timings reg_timings, lut_timings;
int prev_color_mode;
int prev_flags;
int window_type;
u32 max_transmit_size;
u32 extif_clk_period;
unsigned long pix_tx_time;
unsigned long line_upd_time;
struct omapfb_device *fbdev;
struct lcd_ctrl_extif *extif;
const struct lcd_ctrl *int_ctrl;
struct clk *sys_ck;
} hwa742;
struct lcd_ctrl hwa742_ctrl;
static u8 hwa742_read_reg(u8 reg)
{
u8 data;
hwa742.extif->set_bits_per_cycle(8);
hwa742.extif->write_command(®, 1);
hwa742.extif->read_data(&data, 1);
return data;
}
static void hwa742_write_reg(u8 reg, u8 data)
{
hwa742.extif->set_bits_per_cycle(8);
hwa742.extif->write_command(®, 1);
hwa742.extif->write_data(&data, 1);
}
static void set_window_regs(int x_start, int y_start, int x_end, int y_end)
{
u8 tmp[8];
u8 cmd;
x_end--;
y_end--;
tmp[0] = x_start;
tmp[1] = x_start >> 8;
tmp[2] = y_start;
tmp[3] = y_start >> 8;
tmp[4] = x_end;
tmp[5] = x_end >> 8;
tmp[6] = y_end;
tmp[7] = y_end >> 8;
hwa742.extif->set_bits_per_cycle(8);
cmd = HWA742_WINDOW_X_START_0;
hwa742.extif->write_command(&cmd, 1);
hwa742.extif->write_data(tmp, 8);
}
static void set_format_regs(int conv, in