平台 | 内核版本 |
---|---|
RK1108 | Linux3.1 |
设备树修改:
目录:kernel/arch/arm/boot/dts/rv1108-t3-dvr-v10.dts
&sdmmc {
clock-frequency = <50000000>;
clock-freq-min-max = <200000 50000000>;
supports-highspeed;
supports-sd;
broken-cd;
card-detect-delay = <200>;
ignore-pm-notify;
keep-power-in-suspend;
power-inverted;
//status = "okay";
status = "disabled";
};
&sdio {
clock-frequency = <50000000>;
clock-freq-min-max = <200000 50000000>;
supports-highspeed;
supports-sdio;
ignore-pm-notify;
keep-power-in-suspend;
cap-sdio-irq;
status = "disabled";
};
&dwc_control_usb {
vbus_drv = <&gpio0 GPIO_B0 GPIO_ACTIVE_HIGH>;
rockchip,remote_wakeup;
rockchip,usb_irq_wakeup;
status = "okay";
};
&spi0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spim0_clk &spim0_cs0 &spim0_tx &spim0_rx>;
fh8553: fh8553@00 {
status = "okay";
compatible = "rockchip,fh8553";
reg = <0x0>;
spi-max-frequency = <2250000>;
spi-min-frequency = <2250000>;
device_type = "v4l2-spi-subdev";
/* 1 or 2 or 4 */
channels = <1>;
/* 1.8v or 3.3v */
apio_vol = <3300>;
/* PAL or NTSC */
cvbs_mode = "PAL";
//nvp_mode = "720p_2530";
nvp_mode = "1080p_2530";
reset-gpio = <&gpio0 GPIO_C3 GPIO_ACTIVE_LOW>;
//reset-gpio = <&gpio3 GPIO_B0 GPIO_ACTIVE_LOW>;
boot0-gpio = <&gpio0 GPIO_B3 GPIO_ACTIVE_HIGH>;
boot1-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_LOW>;
ver0-gpio = <&gpio3 GPIO_A5 GPIO_ACTIVE_LOW>;
ver1-gpio = <&gpio3 GPIO_A1 GPIO_ACTIVE_LOW>;
ver2-gpio = <&gpio2 GPIO_D6 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&cif_dvp_d2d9 &cif_dvp_clk_in>;
pinctrl-1 = <&cif_dvp_d2d9_sleep &cif_dvp_clk_in_sleep>;
};
};
驱动程序修改:
目录:kernel/drivers/media/platform/rk-cif/fh8553.c
+#include <asm/uaccess.h>
+#define FH_GET_VERSION _IO('p', 2)
+
+#define BOOT_MODE_DOWNLOAD 0x00
+#define BOOT_MODE_NORMAL 0x01
+#define DVR_VER_20 0x20
+#define DVR_VER_13 0x13
struct fh8553 {
struct miscdevice misc;
@@ -88,8 +96,10 @@ struct fh8553 {
int irq;
int boot_sel0_gpio;
int boot_sel1_gpio;
+ int ver_gpio[3];
u8 cif_id;
+ u8 version;
u32 channels;
u32 apio_vol;
const char *fh8553_mode;
@@ -235,35 +245,36 @@ static int fhpreisp_release(struct inode *inode, struct file *file)
return 0;
}
static void fh8553_set_boot_mode(int boot_mode)
{
if (boot_mode == BOOT_MODE_DOWNLOAD) {
gpio_set_value(fh8553->boot_sel0_gpio, GPIO_HIGH);
gpio_set_value(fh8553->boot_sel1_gpio, GPIO_LOW);
} else if (boot_mode == BOOT_MODE_NORMAL) {
gpio_set_value(fh8553->boot_sel0_gpio, GPIO_LOW);
//gpio_set_value(fh8553->boot_sel1_gpio, GPIO_LOW);
return;
}
gpio_set_value(fh8553->reset_gpio, GPIO_HIGH);
mdelay(10);
gpio_set_value(fh8553->reset_gpio, GPIO_LOW);
mdelay(10);
gpio_set_value(fh8553->reset_gpio, GPIO_HIGH);
mdelay(200);
return;
}
static ssize_t fhpreisp_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int ret = 0;
fh8553_set_boot_mode(BOOT_MODE_DOWNLOAD);
if (fh8553->version == DVR_VER_20) {
ret = fh8553_download_fw(fh8553->client, FH_RAMBOOT_NAME, FH_FIRMWARE_NAME);
fh8553_set_boot_mode(BOOT_MODE_NORMAL);
}
return count;
}
static long fhpreisp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = 0;
switch (cmd)
{
case FH_DOWNLOAD_FW:
{
fh8553_set_boot_mode(BOOT_MODE_DOWNLOAD);
if (fh8553->version == 0x20) {
ret = fh8553_download_fw(fh8553->client, FH_RAMBOOT_NAME, FH_FIRMWARE_NAME);
fh8553_set_boot_mode(BOOT_MODE_NORMAL);
}
break;
}
case FH_GET_VERSION:
{
ret = copy_to_user((void __user*)arg, &fh8553->version, 1);
break;
}
default:
ret = -EINVAL;
break;
}
return ret;
}
static void fh8553_version(void)
{
int ret = 0;
int i = 0;
int val = 0;
char gpio_name[32];
enum of_gpio_flags flags;
struct device_node *node;
struct device *dev = &fh8553->client->dev;
node = dev->of_node;
for (i = 0; i < 3; i++) {
memset(gpio_name, 0x00, sizeof(gpio_name));
sprintf(gpio_name, "ver%d-gpio", i);
ret = of_get_named_gpio_flags(node, gpio_name, 0, &flags);
if (ret <= 0) {
dev_warn(dev, "can not find property reset-gpio, error %d\n", ret);
}
fh8553->ver_gpio[i] = ret;
ret = devm_gpio_request(dev, fh8553->ver_gpio[i], gpio_name);
if (ret) {
dev_err(dev, "reset gpio %d request error %d\n", fh8553->ver_gpio[i], ret);
return;
}
ret = gpio_direction_input(fh8553->ver_gpio[i]);
if (ret) {
dev_err(dev, "gpio %d direction input error %d\n", fh8553->ver_gpio[i], ret);
return;
}
val |= (gpio_get_value(fh8553->ver_gpio[i]) << i);
}
if (val == 0x03) {
fh8553->version = DVR_VER_20;
} else {
fh8553->version = DVR_VER_13;
}
printk("fh8553 version:%02X\n", fh8553->version);
}
static int fh8553_hw_config(void)
{
...
fh8553_version();
...
}