mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
add support for newton board
This commit is contained in:
2144
arch/arm/configs/rk29_newton_defconfig
Normal file
2144
arch/arm/configs/rk29_newton_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
1838
arch/arm/mach-rk29/board-rk29-newton.c
Executable file
1838
arch/arm/mach-rk29/board-rk29-newton.c
Executable file
File diff suppressed because it is too large
Load Diff
@@ -214,6 +214,14 @@ struct it7260_platform_data {
|
||||
void (*exit_platform_hw)(void);
|
||||
};
|
||||
|
||||
struct ft5406_platform_data {
|
||||
int (*get_pendown_state)(void);
|
||||
int (*init_platform_hw)(void);
|
||||
int (*ft5406_platform_sleep)(void);
|
||||
int (*ft5406_platform_wakeup)(void);
|
||||
void (*exit_platform_hw)(void);
|
||||
};
|
||||
|
||||
struct akm8975_platform_data {
|
||||
char layouts[3][3];
|
||||
char project_name[64];
|
||||
|
||||
@@ -758,4 +758,13 @@ config TOUCHSCREEN_GT818_IIC
|
||||
config D70_L3188A
|
||||
tristate "D70-L3188A based touchscreens"
|
||||
depends on I2C2_RK29
|
||||
config TOUCHSCREEN_FT5406
|
||||
tristate "FT5406 based touchscreens: FT5406 Interface"
|
||||
depends on I2C2_RK29
|
||||
help
|
||||
say Y here if you have a touchscreen interface using the FT5406
|
||||
controller,and your board-specific initialization code includes that
|
||||
in its table of I2C devices.
|
||||
|
||||
If unsure, say N(but it's safe to say "Y").
|
||||
endif
|
||||
|
||||
@@ -57,4 +57,5 @@ obj-$(CONFIG_TOUCHSCREEN_GT801_IIC) += gt801_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_GT818_IIC) += gt818_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC) += ili2102_ts.o
|
||||
obj-$(CONFIG_D70_L3188A) += goodix_touch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5406) += ft5406_ts.o
|
||||
|
||||
|
||||
1039
drivers/input/touchscreen/ft5406_ts.c
Executable file
1039
drivers/input/touchscreen/ft5406_ts.c
Executable file
File diff suppressed because it is too large
Load Diff
41
drivers/input/touchscreen/ft5406_ts.h
Executable file
41
drivers/input/touchscreen/ft5406_ts.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef __LINUX_FT5X0X_TS_H__
|
||||
#define __LINUX_FT5X0X_TS_H__
|
||||
|
||||
#define SCREEN_MAX_X 1024 //800
|
||||
#define SCREEN_MAX_Y 768 //480
|
||||
#define PRESS_MAX 255
|
||||
|
||||
#define FT5X0X_NAME "ft5x0x_ts"//"synaptics_i2c_rmi"//"synaptics-rmi-ts"//
|
||||
|
||||
struct ft5x0x_ts_platform_data{
|
||||
u16 intr; /* irq number */
|
||||
};
|
||||
|
||||
enum ft5x0x_ts_regs {
|
||||
FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode */
|
||||
};
|
||||
|
||||
//FT5X0X_REG_PMODE
|
||||
#define PMODE_ACTIVE 0x00
|
||||
#define PMODE_MONITOR 0x01
|
||||
#define PMODE_STANDBY 0x02
|
||||
#define PMODE_HIBERNATE 0x03
|
||||
|
||||
|
||||
#ifndef ABS_MT_TOUCH_MAJOR
|
||||
#define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */
|
||||
#define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */
|
||||
#define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */
|
||||
#define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */
|
||||
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
|
||||
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
|
||||
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
|
||||
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
|
||||
#define ABS_MT_BLOB_ID 0x38 /* Group set of pkts as blob */
|
||||
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
|
||||
|
||||
#endif /* ABS_MT_TOUCH_MAJOR */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,6 +155,13 @@ config RTC_HYM8563
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-HYM8563.
|
||||
|
||||
config RTC_DRV_M41T66
|
||||
tristate "ST M41T66"
|
||||
help
|
||||
If you say Y here you will get support for the ST M41T66.
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-m41t80.
|
||||
|
||||
config RTC_DRV_DS1307
|
||||
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
|
||||
help
|
||||
|
||||
@@ -90,3 +90,5 @@ obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
|
||||
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
|
||||
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
|
||||
obj-$(CONFIG_RTC_HYM8563) += rtc-HYM8563.o
|
||||
obj-$(CONFIG_RTC_DRV_M41T66) += rtc-m41t66.o
|
||||
|
||||
|
||||
813
drivers/rtc/rtc-m41t66.c
Executable file
813
drivers/rtc/rtc-m41t66.c
Executable file
@@ -0,0 +1,813 @@
|
||||
/*
|
||||
* I2C client/driver for the ST M41T62 family of i2c rtc chips.
|
||||
*
|
||||
* Author: lhh <lhh@rock-chips.com>
|
||||
*Port to rk29 by yxj
|
||||
*
|
||||
* Based on m41t00.c by Mark A. Greer <mgreer@mvista.com>
|
||||
*
|
||||
* 2010 (c) rockchip
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#define M41T62_REG_SSEC 0
|
||||
#define M41T62_REG_SEC 1
|
||||
#define M41T62_REG_MIN 2
|
||||
#define M41T62_REG_HOUR 3
|
||||
#define M41T62_REG_SQWDAY 4
|
||||
#define M41T62_REG_DAY 5
|
||||
#define M41T62_REG_MON 6
|
||||
#define M41T62_REG_YEAR 7
|
||||
#define M41T62_REG_ALARM_MON 0xa
|
||||
#define M41T62_REG_ALARM_DAY 0xb
|
||||
#define M41T62_REG_ALARM_HOUR 0xc
|
||||
#define M41T62_REG_ALARM_MIN 0xd
|
||||
#define M41T62_REG_ALARM_SEC 0xe
|
||||
#define M41T62_REG_FLAGS 0xf
|
||||
#define M41T62_REG_SQW 0x13
|
||||
|
||||
#define M41T62_REG_SEC_INDEX (M41T62_REG_SEC - 1)
|
||||
#define M41T62_REG_MIN_INDEX (M41T62_REG_MIN - 1)
|
||||
#define M41T62_REG_HOUR_INDEX (M41T62_REG_HOUR - 1)
|
||||
#define M41T62_REG_SQWDAY_INDEX (M41T62_REG_SQWDAY - 1)
|
||||
#define M41T62_REG_DAY_INDEX (M41T62_REG_DAY - 1)
|
||||
#define M41T62_REG_MON_INDEX (M41T62_REG_MON - 1)
|
||||
#define M41T62_REG_YEAR_INDEX (M41T62_REG_YEAR - 1)
|
||||
|
||||
#define M41T62_DATETIME_REG_SIZE (M41T62_REG_YEAR )
|
||||
|
||||
#define M41T62_REG_ALARM_MON_INDEX (M41T62_REG_ALARM_MON-0x0a)
|
||||
#define M41T62_REG_ALARM_DAY_INDEX (M41T62_REG_ALARM_DAY-0x0a)
|
||||
#define M41T62_REG_ALARM_HOUR_INDEX (M41T62_REG_ALARM_HOUR-0x0a)
|
||||
#define M41T62_REG_ALARM_MIN_INDEX (M41T62_REG_ALARM_MIN-0x0a)
|
||||
#define M41T62_REG_ALARM_SEC_INDEX (M41T62_REG_ALARM_SEC-0x0a)
|
||||
#define M41T62_REG_FLAGS_INDEX (M41T62_REG_FLAGS-0x0a)
|
||||
|
||||
|
||||
#define M41T62_ALARM_REG_SIZE \
|
||||
(M41T62_REG_FLAGS + 1 - M41T62_REG_ALARM_MON)
|
||||
|
||||
|
||||
#define M41T62_SEC_ST (1 << 7) /* ST: Stop Bit */
|
||||
#define M41T62_ALMON_AFE (1 << 7) /* AFE: alarm flag Enable Bit */
|
||||
#define M41T62_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */
|
||||
//#define M41T62_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
|
||||
#define M41T62_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
|
||||
//#define M41T62_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
|
||||
#define M41T62_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
|
||||
#define M41T62_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
|
||||
#define M41T62_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
|
||||
|
||||
//#define M41T62_FEATURE_HT (1 << 0) /* Halt feature */
|
||||
//#define M41T62_FEATURE_BL (1 << 1) /* Battery low indicator */
|
||||
//#define M41T62_FEATURE_SQ (1 << 2) /* Squarewave feature */
|
||||
//#define M41T62_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
|
||||
//#define M41T62_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
|
||||
|
||||
#define REPEAT_SEC 5
|
||||
#define REPEAT_MIN 4
|
||||
#define REPEAT_HOUR 3
|
||||
#define REPEAT_DAY 2
|
||||
#define REPEAT_MON 1
|
||||
#define REPEAT_YEAR 0
|
||||
#define RTC_SPEED 100 * 1000
|
||||
|
||||
|
||||
|
||||
#define DRV_VERSION "0.05"
|
||||
#define DRV_NAME "rtc-M41T62"
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO "rtc-M41T62:" x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
//static struct semaphore rtc_sem;//Ryan
|
||||
|
||||
|
||||
struct rock_rtc {
|
||||
int irq;
|
||||
struct i2c_client *client;
|
||||
struct work_struct work;
|
||||
struct mutex mutex;
|
||||
struct rtc_device *rtc;
|
||||
int exiting;
|
||||
struct rtc_wkalrm alarm;
|
||||
struct wake_lock wake_lock;
|
||||
};
|
||||
|
||||
|
||||
static int rtc_alarm_repeat_set(int mod)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t rtc_wakeup_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct rock_rtc *rk_rtc = (struct rock_rtc *)dev_id;
|
||||
DBG("enter %s\n",__func__);
|
||||
disable_irq_nosync(irq);
|
||||
schedule_work(&rk_rtc->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static int m41t62_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, RTC_SPEED);
|
||||
if(ret < 0 )
|
||||
{
|
||||
printk("%s:rtc m41t62 read reg error\n\n\n",__func__);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m41t62_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, RTC_SPEED);
|
||||
if(ret < 0)
|
||||
{
|
||||
printk("%s error>>>>>\n",__func__);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m41t62_init_device(struct i2c_client *client)
|
||||
{
|
||||
//DBG("%s\n",__func__);
|
||||
|
||||
u8 alarmbuf[M41T62_ALARM_REG_SIZE];
|
||||
u8 sqwdayreg;
|
||||
|
||||
//read alarm register current value
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmbuf,M41T62_ALARM_REG_SIZE);
|
||||
|
||||
|
||||
/*DBG("init alarm mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n",
|
||||
alarmbuf[M41T62_REG_ALARM_MON_INDEX],
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX],
|
||||
alarmbuf[M41T62_REG_ALARM_HOUR_INDEX],
|
||||
alarmbuf[M41T62_REG_ALARM_MIN_INDEX],
|
||||
alarmbuf[M41T62_REG_ALARM_SEC_INDEX],
|
||||
alarmbuf[M41T62_REG_FLAGS_INDEX]);*/
|
||||
|
||||
//clear alarm register
|
||||
alarmbuf[M41T62_REG_ALARM_MON_INDEX] &= ~(0x1f | M41T62_ALMON_AFE);
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_ALARM_MIN_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_ALARM_SEC_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_FLAGS_INDEX] = 0;
|
||||
|
||||
//write alarm register
|
||||
m41t62_i2c_set_regs(client,M41T62_REG_ALARM_MON,alarmbuf,M41T62_ALARM_REG_SIZE);
|
||||
|
||||
//set outclk to 32768HZ
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1);
|
||||
sqwdayreg =(sqwdayreg|0x10)&0x1f;
|
||||
m41t62_i2c_set_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1);
|
||||
//m41t62_i2c_read_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1);
|
||||
//printk("sqwdayreg:0x%x\n",sqwdayreg);
|
||||
#if 0
|
||||
sqwdayreg =0;
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&sqwdayreg,1); //YLZ++
|
||||
|
||||
printk("%s:rtc m41t2 flag_reg = 0x%x\n",__func__,sqwdayreg);
|
||||
// if(sqwdayreg & 0x04)
|
||||
{
|
||||
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_SEC,&sqwdayreg,1); //YLZ++
|
||||
printk("%s:rtc m41t2 sec_reg = 0x%x\n",__func__,sqwdayreg);
|
||||
sqwdayreg |= 0x80;
|
||||
m41t62_i2c_set_regs(client,M41T62_REG_SEC,&sqwdayreg,1);
|
||||
sqwdayreg =0x7f;
|
||||
m41t62_i2c_set_regs(client,M41T62_REG_SEC,&sqwdayreg,1);
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_SEC,&sqwdayreg,1); //YLZ++
|
||||
printk("%s:rtc m41t2 sec_reg = 0x%x\n",__func__,sqwdayreg);
|
||||
|
||||
|
||||
}
|
||||
sqwdayreg =0;
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&sqwdayreg,1); //YLZ++
|
||||
printk("%s:rtc m41t2 atfer flag_reg = 0x%x\n",__func__,sqwdayreg);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m41t62_get_datetime(struct i2c_client *client,
|
||||
struct rtc_time *tm)
|
||||
{
|
||||
|
||||
|
||||
struct rock_rtc *rk_rtc = i2c_get_clientdata(client);
|
||||
u8 datetime[M41T62_DATETIME_REG_SIZE];
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
ret = m41t62_i2c_read_regs(client,M41T62_REG_SEC,datetime,M41T62_DATETIME_REG_SIZE);
|
||||
if(ret < 0)
|
||||
{
|
||||
printk("%s:read date time from rtc m41t2 error\n",__func__);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
/*DBG("-------M41T62_REG_SEC=%x--",datetime[M41T62_REG_SEC_INDEX]);
|
||||
DBG("-------M41T62_REG_MIN=%x--",datetime[M41T62_REG_MIN_INDEX]);
|
||||
DBG("-------M41T62_REG_HOUR=%x--",datetime[M41T62_REG_HOUR_INDEX]);
|
||||
DBG("-------M41T62_REG_SQWDAY=%x--",datetime[M41T62_REG_SQWDAY_INDEX]);
|
||||
DBG("-------M41T62_REG_DAY=%x--",datetime[M41T62_REG_DAY_INDEX]);
|
||||
DBG("-------M41T62_REG_MON=%x--",datetime[M41T62_REG_MON_INDEX]);
|
||||
DBG("-------M41T62_REG_YEAR=%x--",datetime[M41T62_REG_YEAR_INDEX]);*/
|
||||
|
||||
tm->tm_sec = bcd2bin(datetime[M41T62_REG_SEC_INDEX]& 0x7f);
|
||||
tm->tm_min = bcd2bin(datetime[M41T62_REG_MIN_INDEX] & 0x7f);
|
||||
tm->tm_hour = bcd2bin(datetime[M41T62_REG_HOUR_INDEX] & 0x3f);
|
||||
tm->tm_mday = bcd2bin(datetime[M41T62_REG_DAY_INDEX] & 0x3f);
|
||||
tm->tm_wday = bcd2bin(datetime[M41T62_REG_SQWDAY_INDEX] & 0x07);
|
||||
tm->tm_mon = bcd2bin(datetime[M41T62_REG_MON_INDEX] & 0x1f) - 1;
|
||||
// assume 20YY not 19YY, and ignore the Century Bit
|
||||
tm->tm_year = bcd2bin(datetime[M41T62_REG_YEAR_INDEX]) + 100;
|
||||
DBG("%s>>>>%4d-%02d-%02d>>wday:%d>>%02d:%02d:%02d>>\n",
|
||||
__func__,tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_wday,
|
||||
tm->tm_hour,tm->tm_min,tm->tm_sec);
|
||||
|
||||
if(tm->tm_year < 100)
|
||||
{
|
||||
printk(KERN_INFO "%s:the time read from the rtc M41T62 is illegal ,\
|
||||
we will use the default time:2010.8.2\n",__func__);
|
||||
tm->tm_sec = 1;
|
||||
tm->tm_min = 7;
|
||||
tm->tm_hour = 7;
|
||||
tm->tm_mday = 2;
|
||||
tm->tm_wday = 4;
|
||||
tm->tm_mon = 7;
|
||||
tm->tm_year = 110;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sets the given date and time to the real time clock. */
|
||||
static int m41t62_set_datetime(struct i2c_client *client, struct rtc_time *tm)
|
||||
{
|
||||
|
||||
struct rock_rtc *rk_rtc = i2c_get_clientdata(client);
|
||||
int ret = 0;
|
||||
u8 datetime[M41T62_DATETIME_REG_SIZE];
|
||||
|
||||
datetime[M41T62_REG_SEC_INDEX] = bin2bcd(tm->tm_sec);
|
||||
datetime[M41T62_REG_MIN_INDEX] = bin2bcd(tm->tm_min);
|
||||
datetime[M41T62_REG_HOUR_INDEX] =bin2bcd(tm->tm_hour) ;
|
||||
datetime[M41T62_REG_SQWDAY_INDEX] =(tm->tm_wday & 0x07) |0x10;
|
||||
datetime[M41T62_REG_DAY_INDEX] = bin2bcd(tm->tm_mday);
|
||||
datetime[M41T62_REG_MON_INDEX] = bin2bcd(tm->tm_mon + 1) ;
|
||||
/* assume 20YY not 19YY */
|
||||
datetime[M41T62_REG_YEAR_INDEX] = bin2bcd(tm->tm_year % 100);
|
||||
printk(KERN_INFO "%s:set time %4d-%02d-%02d %02d:%02d:%02d to rtc \n",__func__,
|
||||
tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
ret = m41t62_i2c_set_regs(client,M41T62_REG_SEC,datetime, M41T62_DATETIME_REG_SIZE);
|
||||
if(ret < 0)
|
||||
{
|
||||
printk(KERN_INFO "%s:set time to rtc m41t62 error\n",__func__);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m41t62_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
//DBG("%s>>>>>>>>>>>\n",__func__);
|
||||
return m41t62_get_datetime(to_i2c_client(dev), tm);
|
||||
}
|
||||
|
||||
static int m41t62_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
//DBG("%s\n",__func__);
|
||||
return m41t62_set_datetime(to_i2c_client(dev), tm);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
|
||||
static int m41t62_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rc;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
DBG("%s>>>>>>>>>%d\n",__func__ ,cmd);
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
break;
|
||||
default:
|
||||
DBG("RTC func m41t62_rtc_ioctl -ENOIOCTLCMD\n");
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
DBG("RTC func m41t62_rtc_ioctl 1\n");
|
||||
rc = i2c_smbus_read_byte_data(client, M41T62_REG_ALARM_MON);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
rc &= ~M41T62_ALMON_AFE;
|
||||
break;
|
||||
case RTC_AIE_ON:
|
||||
rc |= M41T62_ALMON_AFE;
|
||||
break;
|
||||
}
|
||||
DBG("\n@@@@@@@@@@@RTC func m41t62_rtc_ioctl 2@@@@@@@@@@@@@\n");
|
||||
if (i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON, rc) < 0)
|
||||
goto err;
|
||||
DBG("\n@@@@@@@@@@@RTC func m41t62_rtc_ioctl 3@@@@@@@@@@@@@\n");
|
||||
return 0;
|
||||
err:
|
||||
return -EIO;
|
||||
}
|
||||
#else
|
||||
#define m41t62_rtc_ioctl NULL
|
||||
#endif
|
||||
|
||||
static int m41t62_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
//DBG("%s>>>>>>>>>>>>\n",__func__);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct rock_rtc *rk_rtc = i2c_get_clientdata(client);
|
||||
struct rtc_time current_time ;
|
||||
u8 alarmbuf[M41T62_ALARM_REG_SIZE];
|
||||
int ret = 0;
|
||||
|
||||
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
//read the current value of alarm register
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmbuf, M41T62_ALARM_REG_SIZE);
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
|
||||
//clear alarm register
|
||||
alarmbuf[M41T62_REG_ALARM_MON_INDEX] &= ~(0x1f | M41T62_ALMON_AFE);
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] &= ~(0x3f | 0x80);
|
||||
alarmbuf[M41T62_REG_ALARM_MIN_INDEX] = 0;
|
||||
alarmbuf[M41T62_REG_ALARM_SEC_INDEX] = 0;
|
||||
|
||||
|
||||
rk_rtc->alarm = *alarm;
|
||||
DBG("time write to alarm :%4d-%02d-%02d %02d:%02d:%02d>>enable:%d\n",
|
||||
alarm->time.tm_year+1900,
|
||||
alarm->time.tm_mon,
|
||||
alarm->time.tm_mday,
|
||||
alarm->time.tm_hour,
|
||||
alarm->time.tm_min,
|
||||
alarm->time.tm_sec,
|
||||
alarm->enabled);
|
||||
//get current time
|
||||
m41t62_get_datetime(client,¤t_time);
|
||||
DBG("current time :%4d-%02d-%02d %02d:%02d:%02d>>\n",
|
||||
current_time.tm_year+1900,
|
||||
current_time.tm_mon,
|
||||
current_time.tm_mday,
|
||||
current_time.tm_hour,
|
||||
current_time.tm_min,
|
||||
current_time.tm_sec);
|
||||
|
||||
/* offset into rtc's regs */
|
||||
alarmbuf[M41T62_REG_ALARM_SEC_INDEX] |= alarm->time.tm_sec >= 0 ?bin2bcd(alarm->time.tm_sec) : 0x80;
|
||||
alarmbuf[M41T62_REG_ALARM_MIN_INDEX] |= alarm->time.tm_min >= 0 ?bin2bcd(alarm->time.tm_min) : 0x80;
|
||||
alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] |= alarm->time.tm_hour >= 0 ?bin2bcd(alarm->time.tm_hour) : 0x80;
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= alarm->time.tm_mday >= 0 ?bin2bcd(alarm->time.tm_mday) : 0x80;
|
||||
if (alarm->time.tm_mon >= 0)
|
||||
alarmbuf[M41T62_REG_ALARM_MON_INDEX] |= bin2bcd(alarm->time.tm_mon + 1);
|
||||
else
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= 0x40;
|
||||
|
||||
//Ryan@...
|
||||
//DBG("enable mon day");
|
||||
alarmbuf[M41T62_REG_ALARM_MON_INDEX] |= M41T62_ALMON_AFE ;
|
||||
alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= 0xc0;//mon, day repeat
|
||||
//reg[M41T62_REG_ALARM_HOUR] |= 0x80;//hour repeat
|
||||
//reg[M41T62_REG_ALARM_MIN] |= 0x80;//min repeat
|
||||
|
||||
|
||||
|
||||
|
||||
//write alarm register
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
ret = m41t62_i2c_set_regs(client,M41T62_REG_ALARM_MON,alarmbuf, M41T62_DATETIME_REG_SIZE);
|
||||
if(ret < 0)
|
||||
{
|
||||
printk(KERN_INFO "%s:set rtc m41t62 alarm error\n",__func__);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int m41t62_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
||||
{
|
||||
//DBG("%s>>>>>>>>>>>>>\n",__func__);
|
||||
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct rock_rtc *rk_rtc = i2c_get_clientdata(client);
|
||||
u8 alarmreg[M41T62_ALARM_REG_SIZE ]; // all alarm regs and flags
|
||||
int ret = 0;
|
||||
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmreg, M41T62_ALARM_REG_SIZE);
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
|
||||
//printk("read alarm mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n",
|
||||
// reg[M41T62_REG_ALARM_MON],
|
||||
// reg[M41T62_REG_ALARM_DAY],
|
||||
// reg[M41T62_REG_ALARM_HOUR],
|
||||
// reg[M41T62_REG_ALARM_MIN],
|
||||
// reg[M41T62_REG_ALARM_SEC],
|
||||
// reg[M41T62_REG_FLAGS]);
|
||||
t->time.tm_sec = -1;
|
||||
t->time.tm_min = -1;
|
||||
t->time.tm_hour = -1;
|
||||
t->time.tm_mday = -1;
|
||||
t->time.tm_mon = -1;
|
||||
if (!(alarmreg[M41T62_REG_ALARM_SEC_INDEX] & 0x80))
|
||||
t->time.tm_sec = bcd2bin(alarmreg[M41T62_REG_ALARM_SEC_INDEX] & 0x7f);
|
||||
if (!(alarmreg[M41T62_REG_ALARM_MIN_INDEX] & 0x80))
|
||||
t->time.tm_min = bcd2bin(alarmreg[M41T62_REG_ALARM_MIN_INDEX] & 0x7f);
|
||||
if (!(alarmreg[M41T62_REG_ALARM_HOUR_INDEX] & 0x80))
|
||||
t->time.tm_hour = bcd2bin(alarmreg[M41T62_REG_ALARM_HOUR_INDEX] & 0x3f);
|
||||
if (!(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x80))
|
||||
t->time.tm_mday = bcd2bin(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x3f);
|
||||
if (!(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x40))
|
||||
t->time.tm_mon = bcd2bin(alarmreg[M41T62_REG_ALARM_MON_INDEX] & 0x1f) - 1;
|
||||
t->time.tm_year = -1;
|
||||
t->time.tm_wday = -1;
|
||||
t->time.tm_yday = -1;
|
||||
t->time.tm_isdst = -1;
|
||||
t->enabled = !!(alarmreg[M41T62_REG_ALARM_MON_INDEX] & M41T62_ALMON_AFE);
|
||||
t->pending = !!(alarmreg[M41T62_REG_FLAGS_INDEX] & M41T62_FLAGS_AF);
|
||||
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
ret = m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmreg, M41T62_ALARM_REG_SIZE );
|
||||
if(ret < 0)
|
||||
{
|
||||
printk(KERN_INFO "%s:read rtc m41t62 alarm error\n",__func__);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
//printk("read alarm2 mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n",
|
||||
// reg[M41T62_REG_ALARM_MON],
|
||||
// reg[M41T62_REG_ALARM_DAY],
|
||||
// reg[M41T62_REG_ALARM_HOUR],
|
||||
// reg[M41T62_REG_ALARM_MIN],
|
||||
// reg[M41T62_REG_ALARM_SEC],
|
||||
// reg[M41T62_REG_FLAGS]);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rockrtc_work_func(struct work_struct *work)
|
||||
{
|
||||
struct rock_rtc *rk_rtc = container_of(work, struct rock_rtc, work);
|
||||
struct i2c_client *client = rk_rtc->client;
|
||||
struct rtc_time now;
|
||||
u8 flagreg;
|
||||
|
||||
DBG("enter %s\n",__func__);
|
||||
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&flagreg, 1 );
|
||||
flagreg &=~M41T62_FLAGS_AF ;
|
||||
m41t62_i2c_set_regs(client,M41T62_REG_FLAGS,&flagreg, 1 );
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
|
||||
m41t62_get_datetime(client ,&now);
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
if (rk_rtc->alarm.enabled && rk_rtc->alarm.time.tm_sec > now.tm_sec)
|
||||
{
|
||||
long timeout = rk_rtc->alarm.time.tm_sec - now.tm_sec + 1;
|
||||
pr_info("stay awake %lds\n", timeout);
|
||||
wake_lock_timeout(&rk_rtc->wake_lock, timeout * HZ);
|
||||
}
|
||||
if (!rk_rtc->exiting)
|
||||
enable_irq(rk_rtc->irq);
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
}
|
||||
|
||||
|
||||
static struct rtc_class_ops m41t62_rtc_ops = {
|
||||
.read_time = m41t62_rtc_read_time,
|
||||
.set_time = m41t62_rtc_set_time,
|
||||
.read_alarm = m41t62_rtc_read_alarm,
|
||||
.set_alarm = m41t62_rtc_set_alarm,
|
||||
.ioctl = m41t62_rtc_ioctl,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
|
||||
static ssize_t m41t62_sysfs_show_flags(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int val;
|
||||
|
||||
val = i2c_smbus_read_byte_data(client, M41T62_REG_FLAGS);
|
||||
if (val < 0)
|
||||
return -EIO;
|
||||
return sprintf(buf, "%#x\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(flags, S_IRUGO, m41t62_sysfs_show_flags, NULL);
|
||||
|
||||
static ssize_t m41t62_sysfs_show_sqwfreq(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int val;
|
||||
|
||||
val = i2c_smbus_read_byte_data(client, M41T62_REG_SQW);
|
||||
if (val < 0)
|
||||
return -EIO;
|
||||
val = (val >> 4) & 0xf;
|
||||
switch (val) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
val = 32768;
|
||||
break;
|
||||
default:
|
||||
val = 32768 >> val;
|
||||
}
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
static ssize_t m41t62_sysfs_set_sqwfreq(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int almon, sqw;
|
||||
int val = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
if (val) {
|
||||
if (!is_power_of_2(val))
|
||||
return -EINVAL;
|
||||
val = ilog2(val);
|
||||
if (val == 15)
|
||||
val = 1;
|
||||
else if (val < 14)
|
||||
val = 15 - val;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
/* disable SQW, set SQW frequency & re-enable */
|
||||
almon = i2c_smbus_read_byte_data(client, M41T62_REG_ALARM_MON);
|
||||
if (almon < 0)
|
||||
return -EIO;
|
||||
sqw = i2c_smbus_read_byte_data(client, M41T62_REG_SQW);
|
||||
if (sqw < 0)
|
||||
return -EIO;
|
||||
sqw = (sqw & 0x0f) | (val << 4);
|
||||
if (i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON,
|
||||
almon & ~M41T62_ALMON_SQWE) < 0 ||
|
||||
i2c_smbus_write_byte_data(client, M41T62_REG_SQW, sqw) < 0)
|
||||
return -EIO;
|
||||
if (val && i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON,
|
||||
almon | M41T62_ALMON_SQWE) < 0)
|
||||
return -EIO;
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
|
||||
m41t62_sysfs_show_sqwfreq, m41t62_sysfs_set_sqwfreq);
|
||||
|
||||
static struct attribute *attrs[] = {
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_sqwfreq.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group attr_group = {
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
static int m41t62_sysfs_register(struct device *dev)
|
||||
{
|
||||
DBG("\n@@@@@@@@@@@m41t62_sysfs_register@@@@@@@@@@@@@\n");
|
||||
return sysfs_create_group(&dev->kobj, &attr_group);
|
||||
}
|
||||
#else
|
||||
static int m41t62_sysfs_register(struct device *dev)
|
||||
{
|
||||
DBG("\n@@@@@@@@@@@m41t62_sysfs_register@@@@@@@@@@@@@\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
*
|
||||
* Driver Interface
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
static int __devinit m41t62_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
//DBG("%s>>>>>>>>>>>>>client->flags:%d\n",__func__,client->flags);
|
||||
int rc = 0;
|
||||
struct rock_rtc *rk_rtc = NULL;
|
||||
struct rtc_device *rtc = NULL;
|
||||
struct rtc_time tm_read, tm = {
|
||||
.tm_year = 111,
|
||||
.tm_mon = 2,
|
||||
.tm_mday = 7,
|
||||
.tm_wday = 7,
|
||||
.tm_hour = 12,
|
||||
.tm_min = 1,
|
||||
.tm_sec = 8
|
||||
};
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ){
|
||||
rc = -ENODEV;
|
||||
printk("i2c_check_functionality fail\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rk_rtc = kzalloc(sizeof(struct rock_rtc), GFP_KERNEL);
|
||||
if (!rk_rtc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rtc = rtc_device_register(client->name, &client->dev,
|
||||
&m41t62_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc)) {
|
||||
rc = PTR_ERR(rtc);
|
||||
rtc = NULL;
|
||||
printk("\nm41t62_probe err3\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rk_rtc->client = client;
|
||||
rk_rtc->rtc = rtc;
|
||||
|
||||
mutex_init(&rk_rtc->mutex);
|
||||
wake_lock_init(&rk_rtc->wake_lock, WAKE_LOCK_SUSPEND, "rtc_m41t62");
|
||||
INIT_WORK(&rk_rtc->work, rockrtc_work_func);
|
||||
|
||||
i2c_set_clientdata(client, rk_rtc);
|
||||
|
||||
rc = m41t62_sysfs_register(&client->dev);
|
||||
if (rc)
|
||||
{
|
||||
printk("\nm41t62_probe err4\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
m41t62_init_device(client);//0323
|
||||
m41t62_get_datetime(client, &tm_read);
|
||||
if((tm_read.tm_year < 111 ) |(tm_read.tm_year > 120 ) |(tm_read.tm_mon > 11))
|
||||
{
|
||||
m41t62_set_datetime(client, &tm);
|
||||
printk("%s [%d]run set time \n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
if(gpio_request(client->irq, "rtc gpio"))
|
||||
{
|
||||
dev_err(&client->dev, "gpio request fail\n");
|
||||
gpio_free(client->irq);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rk_rtc->irq = gpio_to_irq(client->irq);
|
||||
gpio_pull_updown(client->irq,GPIOPullUp);
|
||||
if (request_irq(rk_rtc->irq, rtc_wakeup_irq, IRQF_TRIGGER_FALLING, client->dev.driver->name, rk_rtc) < 0)
|
||||
{
|
||||
printk("unable to request rtc irq\n");
|
||||
goto exit;
|
||||
}
|
||||
enable_irq_wake(rk_rtc->irq);
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
if (rtc)
|
||||
rtc_device_unregister(rtc);
|
||||
if (rk_rtc)
|
||||
kfree(rk_rtc);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int __devexit m41t62_remove(struct i2c_client *client)
|
||||
{
|
||||
|
||||
struct rock_rtc *rk_rtc = i2c_get_clientdata(client);
|
||||
|
||||
if (rk_rtc->irq > 0) {
|
||||
mutex_lock(&rk_rtc->mutex);
|
||||
rk_rtc->exiting = 1;
|
||||
mutex_unlock(&rk_rtc->mutex);
|
||||
|
||||
free_irq(rk_rtc->irq, rk_rtc);
|
||||
cancel_work_sync(&rk_rtc->work);
|
||||
}
|
||||
|
||||
rtc_device_unregister(rk_rtc->rtc);
|
||||
wake_lock_destroy(&rk_rtc->wake_lock);
|
||||
kfree(rk_rtc);
|
||||
rk_rtc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id m41t62_id[] = {
|
||||
{ DRV_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, m41t62_id);
|
||||
|
||||
|
||||
static struct i2c_driver m41t62_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = m41t62_probe,
|
||||
.remove = __devexit_p(m41t62_remove),
|
||||
.id_table = m41t62_id,
|
||||
|
||||
};
|
||||
|
||||
|
||||
static int __init m41t62_rtc_init(void)
|
||||
{
|
||||
DBG("%s>>>>>>>>>\n",__func__);
|
||||
return i2c_add_driver(&m41t62_driver);
|
||||
}
|
||||
|
||||
static void __exit m41t62_rtc_exit(void)
|
||||
{
|
||||
DBG("%s>>>>>>>>>\n",__func__);
|
||||
i2c_del_driver(&m41t62_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("rockchip lhh");
|
||||
MODULE_DESCRIPTION("ST Microelectronics M41T62 series RTC I2C Client Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
module_init(m41t62_rtc_init);
|
||||
module_exit(m41t62_rtc_exit);
|
||||
@@ -54,6 +54,8 @@ config DEFAULT_OUT_HDMI
|
||||
if you want set HDMI for default panel, android UI size is HDMI default resolution.
|
||||
config LCD_AT070TNA2
|
||||
bool "RGB AT070TNA2"
|
||||
config LCD_AT070TN93
|
||||
bool "RGB AT070TN93"
|
||||
endchoice
|
||||
|
||||
|
||||
|
||||
@@ -29,3 +29,4 @@ obj-$(CONFIG_LCD_LS035Y8DX02A) += lcd_ls035y8dx02a.o
|
||||
obj-$(CONFIG_LCD_IPS1P5680_V1_E) += lcd_ips1p5680_v1_e.o
|
||||
obj-$(CONFIG_LCD_MCU_TFT480800_25_E) += lcd_mcu_tft480800_25_e.o
|
||||
obj-$(CONFIG_LCD_AT070TNA2) += lcd_AT070TNA2.o
|
||||
obj-$(CONFIG_LCD_AT070TN93) += lcd_at070tn93.o
|
||||
76
drivers/video/display/screen/lcd_at070tn93.c
Executable file
76
drivers/video/display/screen/lcd_at070tn93.c
Executable file
@@ -0,0 +1,76 @@
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include "../../rk29_fb.h"
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board.h>
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
/* Base */
|
||||
#define OUT_TYPE SCREEN_RGB
|
||||
|
||||
#define OUT_FACE OUT_D888_P666
|
||||
#define OUT_CLK 58500000 // 65000000
|
||||
#define LCDC_ACLK 500000000//312000000 //29 lcdc axi DMA Ƶ<><C6B5>
|
||||
|
||||
/* Timing */
|
||||
#define H_PW 10
|
||||
#define H_BP 100
|
||||
#define H_VD 800
|
||||
#define H_FP 210
|
||||
|
||||
#define V_PW 10
|
||||
#define V_BP 10
|
||||
#define V_VD 480
|
||||
#define V_FP 18
|
||||
|
||||
#define LCD_WIDTH 202
|
||||
#define LCD_HEIGHT 152
|
||||
/* Other */
|
||||
#define DCLK_POL 0
|
||||
#define SWAP_RB 0
|
||||
|
||||
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
|
||||
{
|
||||
/* screen type & face */
|
||||
screen->type = OUT_TYPE;
|
||||
screen->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen->x_res = H_VD;
|
||||
screen->y_res = V_VD;
|
||||
|
||||
screen->width = LCD_WIDTH;
|
||||
screen->height = LCD_HEIGHT;
|
||||
|
||||
/* Timing */
|
||||
screen->lcdc_aclk = LCDC_ACLK;
|
||||
screen->pixclock = OUT_CLK;
|
||||
screen->left_margin = H_BP;
|
||||
screen->right_margin = H_FP;
|
||||
screen->hsync_len = H_PW;
|
||||
screen->upper_margin = V_BP;
|
||||
screen->lower_margin = V_FP;
|
||||
screen->vsync_len = V_PW;
|
||||
|
||||
/* Pin polarity */
|
||||
screen->pin_hsync = 0;
|
||||
screen->pin_vsync = 0;
|
||||
screen->pin_den = 0;
|
||||
screen->pin_dclk = DCLK_POL;
|
||||
|
||||
/* Swap rule */
|
||||
screen->swap_rb = SWAP_RB;
|
||||
screen->swap_rg = 0;
|
||||
screen->swap_gb = 0;
|
||||
screen->swap_delta = 0;
|
||||
screen->swap_dumy = 0;
|
||||
|
||||
/* Operation function*/
|
||||
screen->init = NULL;
|
||||
screen->standby = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_WM8974 if I2C
|
||||
select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_WM8990 if I2C
|
||||
select SND_SOC_CS42L52 if I2C
|
||||
select SND_SOC_WM8993 if I2C
|
||||
select SND_SOC_WM8994 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_WM9081 if I2C
|
||||
@@ -217,6 +218,9 @@ config SND_SOC_WM8988
|
||||
config SND_SOC_WM8990
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS42L52
|
||||
tristate
|
||||
|
||||
config SND_SOC_WM8993
|
||||
tristate
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ snd-soc-wm8900-objs := wm8900.o
|
||||
snd-soc-alc5621-objs := alc5621.o
|
||||
snd-soc-alc5631-objs := rt5631.o
|
||||
snd-soc-rt5625-objs := rt5625.o
|
||||
snd-soc-cs42l52-objs := cs42l52.o
|
||||
snd-soc-wm8903-objs := wm8903.o
|
||||
snd-soc-wm8940-objs := wm8940.o
|
||||
snd-soc-wm8960-objs := wm8960.o
|
||||
@@ -89,6 +90,7 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
|
||||
obj-$(CONFIG_SND_SOC_alc5621) += snd-soc-alc5621.o
|
||||
obj-$(CONFIG_SND_SOC_alc5631) += snd-soc-alc5631.o
|
||||
obj-$(CONFIG_SND_SOC_RT5625) += snd-soc-rt5625.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
|
||||
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
|
||||
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
|
||||
obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
|
||||
|
||||
1400
sound/soc/codecs/cs42l52.c
Executable file
1400
sound/soc/codecs/cs42l52.c
Executable file
File diff suppressed because it is too large
Load Diff
323
sound/soc/codecs/cs42l52.h
Executable file
323
sound/soc/codecs/cs42l52.h
Executable file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* cs42l52.h -- CS42L52 ALSA SoC audio driver
|
||||
*
|
||||
* Copyright 2007 CirrusLogic, Inc.
|
||||
*
|
||||
* Author: Bo Liu <Bo.Liu@cirrus.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
* Revision history
|
||||
* Nov 2007 Initial version.
|
||||
*/
|
||||
|
||||
#ifndef __CS42L52_H__
|
||||
#define __CS42L52_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <sound/pcm.h>
|
||||
|
||||
|
||||
#define SOC_CS42L52_NAME "CS42L52"
|
||||
#define SOC_CS42L52_DEFAULT_CLK 12000000
|
||||
#define SOC_CS42L52_MIN_CLK 11000000
|
||||
#define SOC_CS42L52_MAX_CLK 27000000
|
||||
#define SOC_CS42L52_DEFAULT_FORMAT SNDRV_PCM_FMTBIT_S16_LE
|
||||
#define SOC_CS42L52_DEFAULT_MAX_CHANS 2
|
||||
#define CS42L52_SYSCLK 1
|
||||
|
||||
|
||||
#define SOC_CS42L52_CHIP_SWICTH (1 << 17)
|
||||
#define SOC_CS42L52_ALL_IN_ONE (1 << 16)
|
||||
#define SOC_CS42L52_CHIP_ONE 0x00
|
||||
#define SOC_CS42L52_CHIP_TWO 0x01
|
||||
#define SOC_CS42L52_CHIP_THR 0x02
|
||||
#define SOC_CS42L52_CHIP_MASK 0x0f
|
||||
#define CS42L52_PB_PIN_INVERRTED (1 << 3)
|
||||
#define CS42L52_PB_PIN_LOW 0
|
||||
#define CS42L52_PB_PIN_HIGN 1
|
||||
#define CS42L52_PB_ALL_ON 2
|
||||
#define CS42L52_PB_ALL_OFF 3
|
||||
|
||||
struct soc_codec_cs42l52 {
|
||||
void (*machine_handler)(unsigned int codec_num);
|
||||
u_int max_playback_stream;
|
||||
u_int max_capture_stream;
|
||||
u_int num_dai;
|
||||
u_int pb_pin_sel;
|
||||
u_int pb_sel;
|
||||
u_int adc_sel1;
|
||||
u_int adc_sel2;
|
||||
u_int mic_sel;
|
||||
u_int sysclk;
|
||||
u_int format;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
struct soc_codec_cs42l52_data{
|
||||
int i2c_bus;
|
||||
u_short i2c_addr;
|
||||
};
|
||||
/*
|
||||
*CS42L52 internal registers
|
||||
*/
|
||||
#define CODEC_CS42L52_CHIP 0x01
|
||||
#define CHIP_ID 0xE0
|
||||
#define CHIP_ID_MASK 0xF8
|
||||
#define CHIP_REV_A0 0x00
|
||||
#define CHIP_REV_A1 0x01
|
||||
#define CHIP_REV_B0 0x02
|
||||
#define CHIP_REV_MASK 0x03
|
||||
|
||||
#define CODEC_CS42L52_PWCTL1 0x02 //0x01
|
||||
#define PWCTL1_PDN_CHRG (1 << 7)
|
||||
#define PWCTL1_PDN_PGAB (1 << 4)
|
||||
#define PWCTL1_PDN_PGAB_SHIFT 4
|
||||
#define PWCTL1_PDN_PGAA (1 << 3)
|
||||
#define PWCTL1_PDN_PGAA_SHIFT 3
|
||||
#define PWCTL1_PDN_ADCB (1 << 2)
|
||||
#define PWCTL1_PDN_ADCB_SHIFT 2
|
||||
#define PWCTL1_PDN_ADCA (1 << 1)
|
||||
#define PWCTL1_PDN_ADCA_SHIFT 1
|
||||
#define PWCTL1_PDN_CODEC (1 << 0)
|
||||
|
||||
#define CODEC_CS42L52_PWCTL2 0x03 //0x07
|
||||
#define PWCTL2_OVRDB (1 << 4)
|
||||
#define PWCTL2_OVRDA (1 << 3)
|
||||
#define PWCTL2_PDN_MICB (1 << 2)
|
||||
#define PWCTL2_PDN_MICB_SHIFT 2
|
||||
#define PWCTL2_PDN_MICA (1 << 1)
|
||||
#define PWCTL2_PDN_MICA_SHIFT 1
|
||||
#define PWCTL2_PDN_MICBIAS (1 << 0)
|
||||
#define PWCTL2_PDN_MICBIAS_SHIFT 0
|
||||
|
||||
#define CODEC_CS42L52_PWCTL3 0x04 //0x08
|
||||
#define PWCTL3_HPB_PDN_SHIFT 6
|
||||
#define PWCTL3_HPB_ON_LOW 0x00
|
||||
#define PWCTL3_HPB_ON_HIGH 0x01
|
||||
#define PWCTL3_HPB_ALWAYS_ON 0x02
|
||||
#define PWCTL3_HPB_ALWAYS_OFF 0x03
|
||||
#define PWCTL3_HPA_PDN_SHIFT 4
|
||||
#define PWCTL3_HPA_ON_LOW 0x00
|
||||
#define PWCTL3_HPA_ON_HIGH 0x01
|
||||
#define PWCTL3_HPA_ALWAYS_ON 0x02
|
||||
#define PWCTL3_HPA_ALWAYS_OFF 0x03
|
||||
#define PWCTL3_SPKB_PDN_SHIFT 2
|
||||
#define PWCTL3_SPKB_ON_LOW 0x00
|
||||
#define PWCTL3_SPKB_ON_HIGH 0x01
|
||||
#define PWCTL3_SPKB_ALWAYS_ON 0x02
|
||||
#define PWCTL3_SPKB_ALWAYS_OFF 0x03
|
||||
#define PWCTL3_SPKA_PDN_SHIFT 0
|
||||
#define PWCTL3_SPKA_ON_LOW 0x00
|
||||
#define PWCTL3_SPKA_ON_HIGH 0x01
|
||||
#define PWCTL3_SPKA_ALWAYS_ON 0x02
|
||||
#define PWCTL3_SPKA_ALWAYS_OFF 0x03
|
||||
#define DEFAULT_OUTPUT_STATE 0x05
|
||||
#define PWCTL3_CONF_MASK 0x03
|
||||
|
||||
|
||||
|
||||
#define CODEC_CS42L52_CLK_CTL 0x05 //0xa0
|
||||
#define CLK_CTL_AUTODECT_ENABLE (1 << 7)
|
||||
#define CLK_CTL_SPEED_SHIFT 5
|
||||
#define CLK_CTL_S_DS_MODE 0x00
|
||||
#define CLK_CTL_S_SS_MODE 0x01
|
||||
#define CLK_CTL_S_HS_MODE 0x02
|
||||
#define CLK_CTL_S_QS_MODE 0x03
|
||||
#define CLK_CTL_32K_SR_SHIFT 4
|
||||
#define CLK_CTL_32K_SR 1
|
||||
#define CLK_CTL_NOT_32K 0
|
||||
#define CLK_CTL_27M_MCLK_SHIFT 3
|
||||
#define CLK_CTL_27M_MCLK 1
|
||||
#define CLK_CTL_NOT_27M 0
|
||||
#define CLK_CTL_RATIO_SHIFT 1
|
||||
#define CLK_CTL_RATIO_128 0x00
|
||||
#define CLK_CTL_RATIO_125 0x01
|
||||
#define CLK_CTL_RATIO_132 0x02
|
||||
#define CLK_CTL_RATIO_136 0x03
|
||||
#define CLK_CTL_MCLKDIV2 1
|
||||
#define CLK_CTL_NOT_MCLKDIV2 0
|
||||
|
||||
|
||||
#define CODEC_CS42L52_IFACE_CTL1 0x06 //0
|
||||
#define IFACE_CTL1_MASTER (1 << 7)
|
||||
#define IFACE_CTL1_INV_SCLK (1 << 6)
|
||||
#define IFACE_CTL1_ADC_FMT_I2S (1 << 5)
|
||||
#define IFACE_CTL1_ADC_FMT_LEFT_J (0 << 5)
|
||||
#define IFACE_CTL1_DSP_MODE_EN (1 << 4)
|
||||
#define IFACE_CTL1_DAC_FMT_LEFT_J (0 << 2)
|
||||
#define IFACE_CTL1_DAC_FMT_I2S (1 << 2)
|
||||
#define IFACE_CTL1_DAC_FMT_RIGHT_J (2 << 2)
|
||||
#define IFACE_CTL1_WL_32BIT (0x00)
|
||||
#define IFACE_CTL1_WL_24BIT (0x01)
|
||||
#define IFACE_CTL1_WL_20BIT (0x02)
|
||||
#define IFACE_CTL1_WL_16BIT (0x03)
|
||||
#define IFACE_CTL1_WL_MASK 0xFFFF
|
||||
|
||||
|
||||
#define CODEC_CS42L52_IFACE_CTL2 0x07 //0
|
||||
#define IFACE_CTL2_SC_MC_EQ (1 << 6)
|
||||
#define IFACE_CTL2_LOOPBACK (1 << 5)
|
||||
#define IFACE_CTL2_S_MODE_OUTPUT_EN (0 << 4)
|
||||
#define IFACE_CTL2_S_MODE_OUTPUT_HIZ (1 << 4)
|
||||
#define IFACE_CTL2_HP_SW_INV (1 << 3)
|
||||
#define IFACE_CTL2_MIC_BIAS_5X 0x00
|
||||
#define IFACE_CTL2_MIC_BIAS_6X 0x01
|
||||
#define IFACE_CTL2_MIC_BIAS_7X 0x02
|
||||
#define IFACE_CTL2_MIC_BIAS_8X 0x03
|
||||
#define IFACE_CTL2_MIC_BIAS_83X 0x04
|
||||
#define IFACE_CTL2_MIC_BIAS_91X 0x05
|
||||
|
||||
#define CODEC_CS42L52_ADC_PGA_A 0x08 //0x81
|
||||
#define CODEC_CS42L52_ADC_PGA_B 0x09 //0x81
|
||||
#define ADC_SEL_SHIFT 5
|
||||
#define PGA_SEL_SHIFT 0
|
||||
#define ADC_SEL_AIN1 0x00
|
||||
#define ADC_SEL_AIN2 0x01
|
||||
#define ADC_SEL_AIN3 0x02
|
||||
#define ADC_SEL_AIN4 0x03
|
||||
#define ADC_SEL_PGA 0x04
|
||||
#define PGA_SEL_NONE 0x00
|
||||
#define PGA_SEL_AIN1 0x01
|
||||
#define PGA_SEL_AIN2 0x02
|
||||
#define PGA_SEL_AIN3 0x04
|
||||
#define PGA_SEL_AIN4 0x08
|
||||
#define PGA_SEL_MIC 0x10
|
||||
#define PGA_SEL_MIC_AIN1 0x11
|
||||
#define PGA_SEL_MIC_AIN1_AIN2 0x13
|
||||
|
||||
#define CODEC_CS42L52_ANALOG_HPF_CTL 0x0A //0xa5
|
||||
#define HPF_CTL_ANLGSFTB (1 << 3)
|
||||
#define HPF_CTL_ANLGSFTA (1 << 0)
|
||||
|
||||
|
||||
#define CODEC_CS42L52_ADC_HPF_FREQ 0x0B //0
|
||||
#define CODEC_CS42L52_ADC_MISC_CTL 0x0C //0
|
||||
#define ADC_MISC_CTL_SOURCE_DSP (1 << 6)
|
||||
|
||||
|
||||
#define CODEC_CS42L52_PB_CTL1 0x0D //0x60
|
||||
#define PB_CTL1_HP_GAIN_SHIFT 5
|
||||
#define PB_CTL1_HP_GAIN_03959 0x00
|
||||
#define PB_CTL1_HP_GAIN_04571 0x01
|
||||
#define PB_CTL1_HP_GAIN_05111 0x02
|
||||
#define PB_CTL1_HP_GAIN_06047 0x03
|
||||
#define PB_CTL1_HP_GAIN_07099 0x04
|
||||
#define PB_CTL1_HP_GAIN_08399 0x05
|
||||
#define PB_CTL1_HP_GAIN_10000 0x06
|
||||
#define PB_CTL1_HP_GAIN_11430 0x07
|
||||
#define PB_CTL1_INV_PCMB (1 << 3)
|
||||
#define PB_CTL1_INV_PCMA (1 << 2)
|
||||
#define PB_CTL1_MSTB_MUTE (1 << 1)
|
||||
#define PB_CTL1_MSTA_MUTE (1 << 0)
|
||||
#define PB_CTL1_MUTE_MASK 0xFFFC
|
||||
|
||||
#define CODEC_CS42L52_MISC_CTL 0x0E //0x02
|
||||
#define MISC_CTL_DEEMPH (1 << 2)
|
||||
#define MISC_CTL_DIGSFT (1 << 1)
|
||||
#define MISC_CTL_DIGZC (1 << 0)
|
||||
|
||||
|
||||
#define CODEC_CS42L52_PB_CTL2 0x0F //0
|
||||
#define PB_CTL2_HPB_MUTE (1 << 7)
|
||||
#define PB_CTL2_HPA_MUTE (1 << 6)
|
||||
#define PB_CTL2_SPKB_MUTE (1 << 5)
|
||||
#define PB_CTL2_SPKA_MUTE (1 << 4)
|
||||
#define PB_CTL2_SPK_SWAP (1 << 2)
|
||||
#define PB_CTL2_SPK_MONO (1 << 1)
|
||||
#define PB_CTL2_SPK_MUTE50 (1 << 0)
|
||||
|
||||
#define CODEC_CS42L52_MICA_CTL 0x10 //0
|
||||
#define CODEC_CS42L52_MICB_CTL 0x11 //0
|
||||
#define MIC_CTL_SEL_MIC1 (0 << 6)
|
||||
#define MIC_CTL_SEL_MIC2 (1 << 6)
|
||||
#define MIC_CTL_SEL_DIFF (1 << 5)
|
||||
|
||||
#define CODEC_CS42L52_PGAA_CTL 0x12 //0
|
||||
#define CODEC_CS42L52_PGAB_CTL 0x13 //0
|
||||
#define PGAX_CTL_VOL_12DB 24
|
||||
#define PGAX_CTL_VOL_6DB 12 /*step size 0.5db*/
|
||||
|
||||
#define CODEC_CS42L52_PASSTHRUA_VOL 0x14 //0
|
||||
#define CODEC_CS42L52_PASSTHRUB_VOL 0x15 //0
|
||||
|
||||
#define CODEC_CS42L52_ADCA_VOL 0x16 //0
|
||||
#define CODEC_CS42L52_ADCB_VOL 0x17 //0
|
||||
#define ADCX_VOL_24DB 24 /*step size 1db*/
|
||||
#define ADCX_VOL_12DB 12
|
||||
#define ADCX_VOL_6DB 6
|
||||
|
||||
#define CODEC_CS42L52_ADCA_MIXER_VOL 0x18 // 0x80
|
||||
#define CODEC_CS42L52_ADCB_MIXER_VOL 0x19 //0x80
|
||||
#define ADC_MIXER_VOL_12DB 0x18
|
||||
|
||||
#define CODEC_CS42L52_PCMA_MIXER_VOL 0x1A //0
|
||||
#define CODEC_CS42L52_PCMB_MIXER_VOL 0x1B //0
|
||||
|
||||
#define CODEC_CS42L52_BEEP_FREQ 0x1C //0
|
||||
#define CODEC_CS42L52_BEEP_VOL 0x1D //0
|
||||
#define BEEP_VOL_12DB 0x06
|
||||
|
||||
|
||||
#define CODEC_CS42L52_BEEP_TONE_CTL 0x1E //0
|
||||
|
||||
#define CODEC_CS42L52_TONE_CTL 0x1F //0x88
|
||||
|
||||
#define CODEC_CS42L52_MASTERA_VOL 0x20 //0
|
||||
#define CODEC_CS42L52_MASTERB_VOL 0x21 //0
|
||||
|
||||
#define CODEC_CS42L52_HPA_VOL 0x22 //0
|
||||
#define CODEC_CS42L52_HPB_VOL 0x23 //0
|
||||
#define DEFAULT_HP_VOL 0x00
|
||||
|
||||
#define CODEC_CS42L52_SPKA_VOL 0x24 //0
|
||||
#define CODEC_CS42L52_SPKB_VOL 0x25 //0
|
||||
#define DEFAULT_SPK_VOL 0x00
|
||||
|
||||
#define CODEC_CS42L52_ADC_PCM_MIXER 0x26 //0
|
||||
|
||||
#define CODEC_CS42L52_LIMITER_CTL1 0x27 //0
|
||||
#define CODEC_CS42L52_LIMITER_CTL2 0x28 //0x7f
|
||||
#define CODEC_CS42L52_LIMITER_AT_RATE 0x29 //0xc0
|
||||
|
||||
#define CODEC_CS42L52_ALC_CTL 0x2A //0
|
||||
#define ALC_CTL_ALCB_ENABLE (1 << 7)
|
||||
#define ALC_CTL_ALCA_ENABLE (1 << 6)
|
||||
#define ALC_CTL_FASTEST_ATTACK 0
|
||||
|
||||
#define CODEC_CS42L52_ALC_RATE 0x2B //0x3f
|
||||
#define ALC_SLOWEST_RELEASE 0x3F
|
||||
|
||||
#define CODEC_CS42L52_ALC_THRESHOLD 0x2C //0
|
||||
#define ALC_MAX_RATE_SHIFT 5
|
||||
#define ALC_MIN_RATE_SHIFT 2
|
||||
#define ALC_RATE_0DB 0
|
||||
#define ALC_RATE_3DB 1
|
||||
#define ALC_RATE_6DB 2
|
||||
|
||||
#define CODEC_CS42L52_NOISE_GATE_CTL 0x2D //0
|
||||
#define NG_ENABLE (1 << 6)
|
||||
#define NG_THRESHOLD_SHIFT 2
|
||||
#define NG_MIN_70DB 2
|
||||
#define NG_DELAY_SHIFT 0
|
||||
#define NG_DELAY_100MS 1
|
||||
|
||||
#define CODEC_CS42L52_CLK_STATUS 0x2E //0
|
||||
#define CODEC_CS42L52_BATT_COMPEN 0x2F //0
|
||||
|
||||
#define CODEC_CS42L52_BATT_LEVEL 0x30 //0
|
||||
#define CODEC_CS42L52_SPK_STATUS 0x31 //0
|
||||
#define SPK_STATUS_PIN_SHIFT 3
|
||||
#define SPK_STATUS_PIN_HIGH 1
|
||||
|
||||
#define CODEC_CS42L52_TEM_CTL 0x32 //0x3b
|
||||
#define CODEC_CS42L52_THE_FOLDBACK 0x33 //0
|
||||
#define CODEC_CS42L52_CHARGE_PUMP 0x34 //0x5f
|
||||
|
||||
|
||||
#define SOC_CS42L52_REG_NUM 56
|
||||
|
||||
extern struct snd_soc_codec_device soc_codec_dev_cs42l52;
|
||||
extern struct snd_soc_dai soc_cs42l52_dai;
|
||||
#endif
|
||||
@@ -74,6 +74,15 @@ config SND_RK29_SOC_WM8994
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on rockchip
|
||||
with the WM8994.
|
||||
|
||||
config SND_RK29_SOC_CS42L52
|
||||
tristate "SoC I2S Audio support for rockchip - CS42L52"
|
||||
depends on SND_RK29_SOC && I2C_RK29
|
||||
select SND_RK29_SOC_I2S
|
||||
select SND_SOC_CS42L52
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on rockchip
|
||||
with the CS42L52.
|
||||
|
||||
config SND_RK29_SOC_RK1000
|
||||
tristate "SoC I2S Audio support for rockchip - RK1000"
|
||||
@@ -84,7 +93,7 @@ config SND_RK29_SOC_RK1000
|
||||
Say Y if you want to add support for SoC audio on rockchip
|
||||
with the RK1000.
|
||||
|
||||
if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_alc5621 || SND_RK29_SOC_alc5631 || SND_RK29_SOC_RT5625
|
||||
if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_alc5621 || SND_RK29_SOC_alc5631 || SND_RK29_SOC_RT5625 || SND_RK29_SOC_CS42L52
|
||||
choice
|
||||
prompt "Set i2s type"
|
||||
config SND_RK29_CODEC_SOC_MASTER
|
||||
|
||||
@@ -10,6 +10,7 @@ snd-soc-wm8900-objs := rk29_wm8900.o
|
||||
snd-soc-alc5621-objs := rk29_alc5621.o
|
||||
snd-soc-alc5631-objs := rk29_rt5631.o
|
||||
snd-soc-rt5625-objs := rk29_rt5625.o
|
||||
snd-soc-cs42l52-objs := rk29_cs42l52.o
|
||||
snd-soc-wm8988-objs := rk29_wm8988.o
|
||||
snd-soc-rk1000-objs := rk29_rk1000codec.o
|
||||
snd-soc-wm8994-objs := rk29_wm8994.o
|
||||
@@ -21,3 +22,4 @@ obj-$(CONFIG_SND_RK29_SOC_alc5621) += snd-soc-alc5621.o
|
||||
obj-$(CONFIG_SND_RK29_SOC_alc5631) += snd-soc-alc5631.o
|
||||
obj-$(CONFIG_SND_RK29_SOC_RT5625) += snd-soc-rt5625.o
|
||||
obj-$(CONFIG_SND_RK29_SOC_RK1000) += snd-soc-rk1000.o
|
||||
obj-$(CONFIG_SND_RK29_SOC_CS42L52) += snd-soc-cs42l52.o
|
||||
|
||||
218
sound/soc/rk29/rk29_cs42l52.c
Executable file
218
sound/soc/rk29/rk29_cs42l52.c
Executable file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* rk29_cs42l52.c -- SoC audio for rockchip
|
||||
*
|
||||
* Driver for rockchip cs42l52 audio
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/rk29_iomap.h>
|
||||
#include "../codecs/cs42l52.h"
|
||||
#include "rk29_pcm.h"
|
||||
#include "rk29_i2s.h"
|
||||
|
||||
#if 1
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
static int rk29_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
unsigned int pll_out = 0;
|
||||
unsigned int lrclk = 0;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
/*by Vincent Hsiung for EQ Vol Change*/
|
||||
#define HW_PARAMS_FLAG_EQVOL_ON 0x21
|
||||
#define HW_PARAMS_FLAG_EQVOL_OFF 0x22
|
||||
if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
|
||||
{
|
||||
ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* set codec DAI configuration */
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set cpu DAI configuration */
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch(params_rate(params)) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
case 24000:
|
||||
case 32000:
|
||||
case 48000:
|
||||
pll_out = 12288000;
|
||||
break;
|
||||
case 11025:
|
||||
case 22050:
|
||||
case 44100:
|
||||
pll_out = 11289600;
|
||||
break;
|
||||
default:
|
||||
DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
|
||||
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
//
|
||||
//
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
|
||||
snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
|
||||
snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
|
||||
#endif
|
||||
DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_LINE("Audio Out", NULL),
|
||||
SND_SOC_DAPM_LINE("Line in", NULL),
|
||||
SND_SOC_DAPM_MIC("Micn", NULL),
|
||||
SND_SOC_DAPM_MIC("Micp", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[]= {
|
||||
|
||||
{"Audio Out", NULL, "HPA"},
|
||||
{"Audio Out", NULL, "HPB"},
|
||||
{"Line in", NULL, "INPUT1A"},
|
||||
{"Line in", NULL, "INPUT1B"},
|
||||
{"Micn", NULL, "INPUT2A"},
|
||||
{"Micp", NULL, "INPUT2B"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a cs42l52 as connected on a rockchip board.
|
||||
*/
|
||||
static int rk29_cs42l52_init(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dai *codec_dai = &codec->dai[0];
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/* Add specific widgets */
|
||||
snd_soc_dapm_new_controls(codec, cs42l52_dapm_widgets,
|
||||
ARRAY_SIZE(cs42l52_dapm_widgets));
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
/* Set up specific audio path audio_mapnects */
|
||||
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
snd_soc_dapm_nc_pin(codec, "HPA");
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
snd_soc_dapm_nc_pin(codec, "HPB");
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
snd_soc_dapm_sync(codec);
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops rk29_ops = {
|
||||
.hw_params = rk29_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link rk29_dai = {
|
||||
.name = "CS42L52",
|
||||
.stream_name = "CS42L52 PCM",
|
||||
.cpu_dai = &rk29_i2s_dai[0],
|
||||
.codec_dai = &soc_cs42l52_dai,
|
||||
.init = rk29_cs42l52_init,
|
||||
.ops = &rk29_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_card_rk29 = {
|
||||
.name = "RK29_CS42L52",
|
||||
.platform = &rk29_soc_platform,
|
||||
.dai_link = &rk29_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
|
||||
static struct snd_soc_device rk29_snd_devdata = {
|
||||
.card = &snd_soc_card_rk29,
|
||||
.codec_dev = &soc_codec_dev_cs42l52,
|
||||
};
|
||||
|
||||
static struct platform_device *rk29_snd_device;
|
||||
|
||||
static int __init audio_card_init(void)
|
||||
{
|
||||
int ret =0;
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__, __LINE__);
|
||||
rk29_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!rk29_snd_device) {
|
||||
DBG("platform device allocation failed\n");
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(rk29_snd_device, &rk29_snd_devdata);
|
||||
rk29_snd_devdata.dev = &rk29_snd_device->dev;
|
||||
ret = platform_device_add(rk29_snd_device);
|
||||
if (ret) {
|
||||
DBG("platform device add failed\n");
|
||||
platform_device_put(rk29_snd_device);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit audio_card_exit(void)
|
||||
{
|
||||
platform_device_unregister(rk29_snd_device);
|
||||
}
|
||||
|
||||
module_init(audio_card_init);
|
||||
module_exit(audio_card_exit);
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("rockchip");
|
||||
MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user