diff --git a/arch/arm/boot/dts/sun8iw12p1-clk.dtsi b/arch/arm/boot/dts/sun8iw12p1-clk.dtsi index 57dc69c2..5b6818db 100644 --- a/arch/arm/boot/dts/sun8iw12p1-clk.dtsi +++ b/arch/arm/boot/dts/sun8iw12p1-clk.dtsi @@ -670,6 +670,11 @@ clocks { }; /*cpus space clocks from PRCM-SPEC*/ + clk_cpurtwi1: cpurtwi1 { + #clock-cells = <0>; + compatible = "allwinner,periph-cpus-clock"; + clock-output-names = "cpurtwi1"; + }; clk_cpurcir: cpurcir { #clock-cells = <0>; compatible = "allwinner,periph-cpus-clock"; diff --git a/arch/arm/boot/dts/sun8iw12p1-pinctrl.dtsi b/arch/arm/boot/dts/sun8iw12p1-pinctrl.dtsi index 3b6f54e3..3e2a5c70 100644 --- a/arch/arm/boot/dts/sun8iw12p1-pinctrl.dtsi +++ b/arch/arm/boot/dts/sun8iw12p1-pinctrl.dtsi @@ -39,6 +39,23 @@ allwinner,pull = <1>; }; + twi4_pins_a: twi4@0 { + allwinner,pins = "PL8", "PL9"; + allwinner,pname = "twi4_scl", "twi4_sda"; + allwinner,function = "s_twi1"; + allwinner,muxsel = <2>; + allwinner,drive = <1>; + allwinner,pull = <0>; + }; + + twi4_pins_b: twi4@1 { + allwinner,pins = "PL8", "PL9"; + allwainner,function = "io_disabled"; + allwinner,muxsel = <7>; + allwinner,drive = <1>; + allwinner,pull = <0>; + }; + s_jtag0_pins_a: s_jtag0@0 { allwinner,pins = "PL4", "PL5", "PL6", "PL7"; allwinner,function = "s_jtag0"; diff --git a/arch/arm/boot/dts/sun8iw12p1.dtsi b/arch/arm/boot/dts/sun8iw12p1.dtsi index dd44004b..dae8e9e0 100644 --- a/arch/arm/boot/dts/sun8iw12p1.dtsi +++ b/arch/arm/boot/dts/sun8iw12p1.dtsi @@ -33,6 +33,7 @@ twi1 = &twi1; twi2 = &twi2; twi3 = &twi3; + twi4 = &twi4; spi0 = &spi0; spi1 = &spi1; spi2 = &spi2; @@ -633,6 +634,21 @@ status = "disabled"; }; + twi4: twi@0x07081800{ + #address-cells = <1>; + #size-cells = <0>; + compatible = "allwinner,sun8i-twi"; + device_type = "twi4"; + reg = <0x0 0x07081800 0x0 0x400>; + interrupts = ; + clocks = <&clk_cpurtwi1>; + clock-frequency = <200000>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&twi4_pins_a>; + pinctrl-1 = <&twi4_pins_b>; + status = "disabled"; + }; + usbc0:usbc0@0 { device_type = "usbc0"; compatible = "allwinner,sunxi-otg-manager"; diff --git a/arch/arm/mach-sunxi/include/mach/uncompress.h b/arch/arm/mach-sunxi/include/mach/uncompress.h index 7d7edfc9..107ea66c 100644 --- a/arch/arm/mach-sunxi/include/mach/uncompress.h +++ b/arch/arm/mach-sunxi/include/mach/uncompress.h @@ -26,7 +26,8 @@ #include #include -#define SUNXI_UART0_PBASE 0x01c28000 +#ifdef CONFIG_DEBUG_LL +#define SUNXI_UART0_PBASE CONFIG_DEBUG_UART_PHYS #define UART_TF (*(volatile unsigned long*)(SUNXI_UART0_PBASE + 0x00)) #define UART_SR (*(volatile unsigned long*)(SUNXI_UART0_PBASE + 0x7C)) #define TX_BUSY BIT(1) @@ -35,12 +36,13 @@ */ static inline void putc(int c) { -#if 0 while (!(UART_SR & TX_BUSY)) cpu_relax(); UART_TF = c; -#endif } +#else +static inline void putc(int c){} +#endif static inline void flush(void) {} static inline void arch_decomp_setup(void) {} diff --git a/drivers/clk/sunxi/clk-sun8iw12.c b/drivers/clk/sunxi/clk-sun8iw12.c index 5e99d623..e5b101bb 100644 --- a/drivers/clk/sunxi/clk-sun8iw12.c +++ b/drivers/clk/sunxi/clk-sun8iw12.c @@ -455,6 +455,7 @@ static const char *cpurahbs_parents[] = {"cpurcpus"}; static const char *cpurapbs1_parents[] = {"cpurahbs"}; static const char *cpurapbs2_pll_parents[] = {"pll_periph0"}; static const char *cpurapbs2_parents[] = {"hosc", "losc", "iosc", "cpurapbs2_pll"}; +static const char *apbs2mod_parents[] = {"cpurapbs2"}; static const char *cpurdev_parents[] = {"losc", "hosc"}; static const char *cpurpio_parents[] = {"cpurapbs1"}; static const char *losc_parents[] = {"losc"}; @@ -573,6 +574,7 @@ SUNXI_CLK_PERIPH(cpurapbs1, 0, 0, 0, CPUS_AP SUNXI_CLK_PERIPH(cpurapbs2_pll, 0, 0, 0, CPUS_APBS2_CFG, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &clk_lock, NULL, 0); SUNXI_CLK_PERIPH(cpurapbs2, CPUS_APBS2_CFG, 24, 2, CPUS_APBS2_CFG, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, &clk_lock, NULL, 0); SUNXI_CLK_PERIPH(cpurcir, CPUS_CIR_CFG, 24, 1, CPUS_CIR_CFG, 0, 5, 8, 2, 0, CPUS_CIR_CFG, CPUS_CIR_GATE, CPUS_CIR_GATE, 0, 31, 16, 0, 0, &clk_lock, NULL, 0); +SUNXI_CLK_PERIPH(cpurtwi1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CPUS_TWI_GATE, CPUS_TWI_GATE, 0, 0, 17, 1, 0, &clk_lock, NULL, 0); SUNXI_CLK_PERIPH(losc_out, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LOSC_OUT_GATE, 0, 0, 0, 0, 0, &clk_lock, NULL, 0); SUNXI_CLK_PERIPH(cpurpio, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &clk_lock, NULL, 0); SUNXI_CLK_PERIPH(spwm, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CPUS_PWM_GATE, CPUS_PWM_GATE, 0, 0, 16, 0, 0, &clk_lock, NULL, 0); @@ -680,6 +682,7 @@ struct periph_init_data sunxi_periphs_cpus_init[] = { {"cpurapbs1", CLK_GET_RATE_NOCACHE|CLK_READONLY, cpurapbs1_parents, ARRAY_SIZE(cpurapbs1_parents), &sunxi_clk_periph_cpurapbs1 }, {"cpurapbs2_pll", CLK_GET_RATE_NOCACHE|CLK_READONLY, cpurapbs2_pll_parents, ARRAY_SIZE(cpurapbs2_pll_parents), &sunxi_clk_periph_cpurapbs2_pll }, {"cpurapbs2", CLK_GET_RATE_NOCACHE|CLK_READONLY, cpurapbs2_parents, ARRAY_SIZE(cpurapbs2_parents), &sunxi_clk_periph_cpurapbs2 }, + {"cpurtwi1", 0, apbs2mod_parents, ARRAY_SIZE(apbs2mod_parents), &sunxi_clk_periph_cpurtwi1 }, {"cpurcir", CLK_GET_RATE_NOCACHE, cpurdev_parents, ARRAY_SIZE(cpurdev_parents), &sunxi_clk_periph_cpurcir }, {"losc_out", 0, losc_parents, ARRAY_SIZE(losc_parents), &sunxi_clk_periph_losc_out }, {"cpurpio", CLK_GET_RATE_NOCACHE|CLK_READONLY, cpurpio_parents, ARRAY_SIZE(cpurpio_parents), &sunxi_clk_periph_cpurpio }, diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 34cfc0eb..67ac9daa 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -88,14 +88,16 @@ static int i2c_gpio_getscl(void *data) static int of_i2c_gpio_get_pins(struct device_node *np, unsigned int *sda_pin, unsigned int *scl_pin) { - if (of_gpio_count(np) < 2) - return -ENODEV; - - *sda_pin = of_get_gpio(np, 0); - *scl_pin = of_get_gpio(np, 1); + if (of_gpio_count(np) < 2) { + *sda_pin = of_get_named_gpio_flags(np, "i2c-gpio,sda", 0, NULL); + *scl_pin = of_get_named_gpio_flags(np, "i2c-gpio,scl", 0, NULL); + } else { + *sda_pin = of_get_gpio(np, 0); + *scl_pin = of_get_gpio(np, 1); - if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER) + return -EPROBE_DEFER; + } if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) { pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", @@ -220,7 +222,7 @@ static int i2c_gpio_probe(struct platform_device *pdev) adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; - adap->nr = pdev->id; + adap->nr = -1; ret = i2c_bit_add_numbered_bus(adap); if (ret) return ret; diff --git a/drivers/i2c/busses/i2c-sunxi.c b/drivers/i2c/busses/i2c-sunxi.c index 624e67e8..32237ce5 100644 --- a/drivers/i2c/busses/i2c-sunxi.c +++ b/drivers/i2c/busses/i2c-sunxi.c @@ -54,8 +54,6 @@ module_param_named(transfer_debug, bus_transfer_dbg, #define SUNXI_I2C_SFAIL -3 /* start fail */ #define SUNXI_I2C_TFAIL -4 /* stop fail */ -static int twi_used_mask; - /* I2C transfer status */ enum { I2C_XFER_IDLE = 0x1, @@ -337,11 +335,6 @@ static int sunxi_i2c_xfer_complete(struct sunxi_i2c *i2c, int code); static int sunxi_i2c_do_xfer(struct sunxi_i2c *i2c, struct i2c_msg *msgs, int num); -static int twi_chan_is_enable(int _ch) -{ - return twi_used_mask & SUNXI_TWI_CHAN_MASK(_ch); -} - static int twi_select_gpio_state(struct pinctrl *pctrl, char *name, u32 no) { int ret = 0; @@ -367,9 +360,6 @@ static int twi_request_gpio(struct sunxi_i2c *i2c) I2C_DBG("Pinctrl init %d ... [%s]\n", i2c->bus_num, i2c->adap.dev.parent->init_name); - if (!twi_chan_is_enable(i2c->bus_num)) - return -1; - i2c->pctrl = devm_pinctrl_get(i2c->adap.dev.parent); if (IS_ERR(i2c->pctrl)) { I2C_ERR("TWI%d devm_pinctrl_get() failed! return %ld\n", @@ -395,7 +385,7 @@ static int twi_start(void __iomem *base_addr, int bus_num) while ((twi_get_start(base_addr) == 1) && (--timeout)) ; if (timeout == 0) { - I2C_ERR("[i2c%d] START can't sendout!\n", bus_num); + I2C_ERR("[sunxi-i2c%d] START can't sendout!\n", bus_num); return SUNXI_I2C_FAIL; } @@ -411,7 +401,7 @@ static int twi_restart(void __iomem *base_addr, int bus_num) while ((twi_get_start(base_addr) == 1) && (--timeout)) ; if (timeout == 0) { - I2C_ERR("[i2c%d] Restart can't sendout!\n", bus_num); + I2C_ERR("[sunxi-i2c%d] Restart can't sendout!\n", bus_num); return SUNXI_I2C_FAIL; } @@ -429,7 +419,7 @@ static int twi_stop(void __iomem *base_addr, int bus_num) while ((twi_get_stop(base_addr) == 1) && (--timeout)) ; if (timeout == 0) { - I2C_ERR("[i2c%d] STOP can't sendout!\n", bus_num); + I2C_ERR("[sunxi-i2c%d] STOP can't sendout!\n", bus_num); return SUNXI_I2C_TFAIL; } @@ -438,7 +428,7 @@ static int twi_stop(void __iomem *base_addr, int bus_num) && (--timeout)) ; if (timeout == 0) { - I2C_ERR("[i2c%d] i2c state(0x%08x) isn't idle(0xf8)\n", + I2C_ERR("[sunxi-i2c%d] i2c state(0x%08x) isn't idle(0xf8)\n", bus_num, readl(base_addr + TWI_STAT_REG)); return SUNXI_I2C_TFAIL; } @@ -450,7 +440,7 @@ static int twi_stop(void __iomem *base_addr, int bus_num) ; if (timeout == 0) { - I2C_ERR("[i2c%d] i2c lcr(0x%08x) isn't idle(0x3a)\n", + I2C_ERR("[sunxi-i2c%d] i2c lcr(0x%08x) isn't idle(0x3a)\n", bus_num, readl(base_addr + TWI_LCR_REG)); return SUNXI_I2C_TFAIL; } @@ -539,7 +529,7 @@ static int twi_send_clk_9pulse(void __iomem *base_addr, int bus_num) twi_disable_lcr(base_addr, twi_scl); status = SUNXI_I2C_OK; } else { - I2C_ERR("[i2c%d] SDA is still Stuck Low, failed.\n", bus_num); + I2C_ERR("[sunxi-i2c%d] SDA is still Stuck Low, failed.\n", bus_num); twi_disable_lcr(base_addr, twi_scl); status = SUNXI_I2C_FAIL; } @@ -1053,19 +1043,19 @@ static int sunxi_i2c_hw_init(struct sunxi_i2c *i2c, ret = twi_regulator_request(pdata); if (ret < 0) { - I2C_ERR("[i2c%d] request regulator failed!\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] request regulator failed!\n", i2c->bus_num); return -1; } twi_regulator_enable(pdata); ret = twi_request_gpio(i2c); if (ret < 0) { - I2C_ERR("[i2c%d] request i2c gpio failed!\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] request i2c gpio failed!\n", i2c->bus_num); return -1; } if (sunxi_i2c_clk_init(i2c)) { - I2C_ERR("[i2c%d] init i2c clock failed!\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] init i2c clock failed!\n", i2c->bus_num); return -1; } @@ -1190,13 +1180,12 @@ static int sunxi_i2c_probe(struct platform_device *pdev) } pdev->dev.platform_data = pdata; - pdev->id = of_alias_get_id(np, "twi"); - if (pdev->id < 0) { + pdata->bus_num = of_alias_get_id(np, "twi"); + if (pdata->bus_num < 0) { I2C_ERR("I2C failed to get alias id\n"); ret = -EINVAL; goto emem; } - pdata->bus_num = pdev->id; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (mem_res == NULL) { @@ -1234,7 +1223,7 @@ static int sunxi_i2c_probe(struct platform_device *pdev) pdev->dev.release = sunxi_i2c_release; i2c->adap.owner = THIS_MODULE; - i2c->adap.nr = pdata->bus_num; + i2c->adap.nr = pdata->bus_num;; i2c->adap.retries = 3; i2c->adap.timeout = 5*HZ; i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; @@ -1267,14 +1256,13 @@ static int sunxi_i2c_probe(struct platform_device *pdev) ret = request_irq(irq, sunxi_i2c_handler, int_flag, i2c->adap.name, i2c); if (ret) { - I2C_ERR("[i2c%d] requeset irq failed!\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] requeset irq failed!\n", i2c->bus_num); goto ereqirq; } i2c->adap.algo_data = i2c; i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; - twi_used_mask |= SUNXI_TWI_CHAN_MASK(pdev->id); if (sunxi_i2c_hw_init(i2c, pdata)) { ret = -EIO; @@ -1283,7 +1271,7 @@ static int sunxi_i2c_probe(struct platform_device *pdev) ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { - I2C_ERR("[i2c%d] failed to add adapter\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] failed to add adapter\n", i2c->bus_num); goto eadapt; } @@ -1334,7 +1322,7 @@ static int sunxi_i2c_remove(struct platform_device *pdev) { struct sunxi_i2c *i2c = platform_get_drvdata(pdev); - I2C_DBG("[i2c.%d] remove ...\n", i2c->bus_num); + I2C_DBG("[sunxi-i2c.%d] remove ...\n", i2c->bus_num); platform_set_drvdata(pdev, NULL); i2c_del_adapter(&i2c->adap); @@ -1381,7 +1369,7 @@ static int sunxi_i2c_suspend(struct device *dev) i2c->suspended = 1; if (sunxi_i2c_clk_exit(i2c)) { - I2C_ERR("[i2c%d] suspend failed..\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] suspend failed..\n", i2c->bus_num); i2c->suspended = 0; return -1; } @@ -1389,7 +1377,7 @@ static int sunxi_i2c_suspend(struct device *dev) twi_select_gpio_state(i2c->pctrl, PINCTRL_STATE_SLEEP, i2c->bus_num); twi_regulator_disable(dev->platform_data); - I2C_DBG("[i2c%d] suspend okay..\n", i2c->bus_num); + I2C_DBG("[sunxi-i2c%d] suspend okay..\n", i2c->bus_num); return 0; } @@ -1410,13 +1398,13 @@ static int sunxi_i2c_resume(struct device *dev) twi_select_gpio_state(i2c->pctrl, PINCTRL_STATE_DEFAULT, i2c->bus_num); if (sunxi_i2c_clk_init(i2c)) { - I2C_ERR("[i2c%d] resume failed..\n", i2c->bus_num); + I2C_ERR("[sunxi-i2c%d] resume failed..\n", i2c->bus_num); return -1; } twi_soft_reset(i2c->base_addr); - I2C_DBG("[i2c%d] resume okay..\n", i2c->bus_num); + I2C_DBG("[sunxi-i2c%d] resume okay..\n", i2c->bus_num); return 0; } diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index a7966ecb..b46c2409 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -860,18 +860,23 @@ static int inv_mpu_probe(struct i2c_client *client, struct inv_mpu6050_state *st; struct iio_dev *indio_dev; struct inv_mpu6050_platform_data *pdata; +#if defined(CONFIG_OF) + struct device_node *np = client->dev.of_node; +#endif #if defined(CONFIG_MPU_ALLWINNER) struct gpio_config int_gpio_config; - struct device_node *mpu_node = NULL; int mpu_int_gpio = 0; #endif int result; -#if defined(CONFIG_MPU_ALLWINNER) - mpu_node = of_find_node_by_name(NULL, "imu_para"); - if (mpu_node != NULL) { - mpu_int_gpio = of_get_named_gpio_flags(mpu_node, "imu-int-gpio", 0, - (enum of_gpio_flags *)&int_gpio_config); + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_I2C_BLOCK)) + return -ENOSYS; + +#if defined(CONFIG_MPU_ALLWINNER) && defined(CONFIG_OF) + mpu_int_gpio = of_get_named_gpio_flags(np, "imu-int-gpio", 0, + (enum of_gpio_flags *)&int_gpio_config); + if (gpio_is_valid(mpu_int_gpio)) { client->irq = gpio_to_irq(mpu_int_gpio); printk("mpu6050: %d:%d\n", mpu_int_gpio, client->irq); } else { @@ -879,11 +884,6 @@ static int inv_mpu_probe(struct i2c_client *client, } #endif - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_I2C_BLOCK)) - return -ENOSYS; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -894,6 +894,7 @@ static int inv_mpu_probe(struct i2c_client *client, pdata = dev_get_platdata(&client->dev); if (pdata) st->plat_data = *pdata; + /* power is turned on inside check chip type*/ result = inv_check_and_setup_chip(st, id); if (result) @@ -1030,10 +1031,12 @@ static const unsigned short normal_i2c[2] = {0x68, I2C_CLIENT_END}; static int inv_mpu_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - if (adapter->nr == 0) { - strlcpy(info->type, "mpu6500", 20); + int ret = 0; + + ret = i2c_smbus_read_byte_data(client, INV_MPU6050_REG_WHO_AM_I); + if (ret == INV_MPU6050_CHIP_ID) return 0; - } + dev_err(&client->dev, "failed :select i2c device\n"); return -ENODEV; } diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 22289311..922d5b3f 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -171,6 +171,7 @@ struct inv_mpu6050_state { #define INV_MPU6050_REG_FIFO_COUNT_H 0x72 #define INV_MPU6050_REG_FIFO_R_W 0x74 +#define INV_MPU6050_REG_WHO_AM_I 0x75 #define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6 #define INV_MPU6050_FIFO_COUNT_BYTE 2 @@ -202,6 +203,8 @@ struct inv_mpu6050_state { #define INV_MPU6050_ONE_K_HZ 1000 #define INV_MPU6050_8K_HZ 8000 +#define INV_MPU6050_CHIP_ID 0x98 + /* #define POLL_WORK */ /* scan element definition */ diff --git a/drivers/input/touchscreen/ft6x/Kconfig b/drivers/input/touchscreen/ft6x/Kconfig index aa764618..5742dce2 100755 --- a/drivers/input/touchscreen/ft6x/Kconfig +++ b/drivers/input/touchscreen/ft6x/Kconfig @@ -8,3 +8,13 @@ config TOUCHSCREEN_FT6X_TS depends on INPUT && I2C help ft6x touchscreen driver + + +config FT6X_MULTITOUCH_TS +bool "support ft6x touchscreen to multtouch" + depends on TOUCHSCREEN_FT6X_TS + default n + help + Say Y here if you want to open multtouch. + + If unsure, say N. diff --git a/drivers/input/touchscreen/ft6x/focaltech_core.c b/drivers/input/touchscreen/ft6x/focaltech_core.c index d0c39a69..b40689a7 100755 --- a/drivers/input/touchscreen/ft6x/focaltech_core.c +++ b/drivers/input/touchscreen/ft6x/focaltech_core.c @@ -56,8 +56,8 @@ //#define FTS_DBG #ifdef FTS_DBG #define ENTER printk(KERN_INFO "[FTS_DBG] func: %s line: %04d\n", __func__, __LINE__); -#define PRINT_DBG(x...) printk(KERN_INFO "[FTS_DBG] " x) -#define PRINT_INFO(x...) printk(KERN_INFO "[FTS_INFO] " x) +#define PRINT_DBG(x...) pr_debug("[FTS_DBG] " x) +#define PRINT_INFO(x...) pr_info("[FTS_INFO] " x) #define PRINT_WARN(x...) printk(KERN_INFO "[FTS_WARN] " x) #define PRINT_ERR(format,x...) printk(KERN_ERR "[FTS_ERR] func: %s line: %04d info: " format, __func__, __LINE__, ## x) #else @@ -168,6 +168,25 @@ static void fts_virtual_keys_init(void) #endif +/** + * ctp_print_info - sysconfig print function + * return value: + * + */ +static void ctp_print_info(struct ctp_config_info_ft6x *info) +{ + PRINT_DBG("info->ctp_used:%d\n", info->ctp_used); + PRINT_DBG("info->twi_id:%d\n", info->twi_id); + PRINT_DBG("info->screen_max_x:%d\n", info->screen_max_x); + PRINT_DBG("info->screen_max_y:%d\n", info->screen_max_y); + PRINT_DBG("info->revert_x_flag:%d\n", info->revert_x_flag); + PRINT_DBG("info->revert_y_flag:%d\n", info->revert_y_flag); + PRINT_DBG("info->exchange_x_y_flag:%d\n", info->exchange_x_y_flag); + PRINT_DBG("info->irq_gpio_number:%d\n", info->irq_gpio.gpio); + PRINT_DBG("info->wakeup_gpio_number:%d\n", info->wakeup_gpio.gpio); +} + + /******************************************************************************* * Name: fts_i2c_read * Brief: @@ -368,7 +387,17 @@ static int fts_update_data(void) ft_size = 0x09; } if((buf[6*i+3] & 0x40) == 0x0) { -#if CONFIG_FT6X_MULTITOUCH //单、多点触摸选择 + if (exchange_x_y_flag == 1) + swap(x, y); + if (revert_x_flag == 1) + x = screen_max_x - x; + if (revert_y_flag == 1) + y = screen_max_y - y; + if (x > screen_max_x || x < 0 || + y > screen_max_y || y < 0) + return -1; + +#ifdef CONFIG_FT6X_MULTITOUCH /* 单、多点触摸选择 */ #if MULTI_PROTOCOL_TYPE_B input_mt_slot(data->input_dev, buf[6*i+5]>>4); input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true); @@ -386,20 +415,6 @@ static int fts_update_data(void) #else //单点 - if(1 == exchange_x_y_flag){ - swap(x, y); - } - if(1 == revert_x_flag){ - x = screen_max_x - x; - } - if(1 == revert_y_flag){ - y = screen_max_y - y; - } - if(x > screen_max_x || x<0 ||y>screen_max_y || y<0){ - - return -1; - } - input_report_abs(data->input_dev, ABS_X, x); input_report_abs(data->input_dev, ABS_Y, y); @@ -768,6 +783,7 @@ static int ctp_get_sysconfig(struct device_node *np, struct ctp_config_info_ft6x info->screen_max_y = 240; pr_err("failed to get ctp_screen_max_y\n"); } + ctp_print_info(info); return ret; } @@ -881,7 +897,7 @@ static int fts_probe(struct i2c_client *client, const struct i2c_device_id *id) #endif fts->input_dev = input_dev; -#if CONFIG_FT6X_MULTITOUCH //单、多点触摸选择 +#ifdef CONFIG_FT6X_MULTITOUCH /* 单、多点触摸选择 */ __set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit); __set_bit(ABS_MT_POSITION_X, input_dev->absbit); __set_bit(ABS_MT_POSITION_Y, input_dev->absbit); @@ -1149,24 +1165,6 @@ static int ctp_detect(struct i2c_client *client, struct i2c_board_info *info) } } -/** - * ctp_print_info - sysconfig print function - * return value: - * - */ -void ctp_print_info(struct ctp_config_info_ft6x info) -{ - printk("info.ctp_used:%d\n",info.ctp_used); - printk("info.twi_id:%d\n",info.twi_id); - printk("info.screen_max_x:%d\n",info.screen_max_x); - printk("info.screen_max_y:%d\n",info.screen_max_y); - printk("info.revert_x_flag:%d\n",info.revert_x_flag); - printk("info.revert_y_flag:%d\n",info.revert_y_flag); - printk("info.exchange_x_y_flag:%d\n",info.exchange_x_y_flag); - printk("info.irq_gpio_number:%d\n",info.irq_gpio.gpio); - printk("info.wakeup_gpio_number:%d\n",info.wakeup_gpio.gpio); -} - /******************************************************************************* * Name: fts_init * Brief: diff --git a/drivers/input/touchscreen/ft6x/focaltech_core.h b/drivers/input/touchscreen/ft6x/focaltech_core.h index 3748e221..0e7d295a 100755 --- a/drivers/input/touchscreen/ft6x/focaltech_core.h +++ b/drivers/input/touchscreen/ft6x/focaltech_core.h @@ -137,7 +137,9 @@ //#define TOUCH_VIRTUAL_KEYS #define MULTI_PROTOCOL_TYPE_B 0 #define TS_MAX_FINGER 1 -#define CONFIG_FT6X_MULTITOUCH 0 + +/*configure this macro by meuconfig*/ +#define CONFIG_FT6X_MULTITOUCH IS_ENABLED(FT6X_MULTITOUCH_TS) #define FTS_PACKET_LENGTH 128 diff --git a/drivers/media/platform/sunxi-vin/Makefile b/drivers/media/platform/sunxi-vin/Makefile index 8a7b7661..01c24d12 100644 --- a/drivers/media/platform/sunxi-vin/Makefile +++ b/drivers/media/platform/sunxi-vin/Makefile @@ -20,9 +20,7 @@ vin_v4l2-y += vin-mipi/sunxi_mipi.o vin_v4l2-y += vin-mipi/bsp_mipi_csi_null.o vin_v4l2-y += vin-mipi/combo_rx/combo_rx_reg.o vin_v4l2-y += vin-isp/sunxi_isp.o -vin_v4l2-y += vin-isp/bsp_isp.o \ - vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.o \ - vin-isp/isp_platform_drv.o +vin_v4l2-y += vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.o vin_v4l2-y += vin-vipp/sunxi_scaler.o vin_v4l2-y += vin-vipp/vipp_reg.o diff --git a/drivers/media/platform/sunxi-vin/modules/sensor/sensor_helper.c b/drivers/media/platform/sunxi-vin/modules/sensor/sensor_helper.c index 0fd83829..f0216bf2 100644 --- a/drivers/media/platform/sunxi-vin/modules/sensor/sensor_helper.c +++ b/drivers/media/platform/sunxi-vin/modules/sensor/sensor_helper.c @@ -146,8 +146,10 @@ static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd, /*judge if sensor have wdr command win*/ if (info->isp_wdr_mode == ISP_COMANDING_MODE) { for (i = 0; i < info->win_size_num; ++i) { - if (ws->wdr_mode == ISP_COMANDING_MODE) + if (ws->wdr_mode == ISP_COMANDING_MODE) { + best_ws = ws; break; + } ++ws; } if (i == info->win_size_num) @@ -158,8 +160,10 @@ static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd, ws = info->win_pt; if (info->isp_wdr_mode == ISP_DOL_WDR_MODE) { for (i = 0; i < info->win_size_num; ++i) { - if (ws->wdr_mode == ISP_DOL_WDR_MODE) + if (ws->wdr_mode == ISP_DOL_WDR_MODE) { + best_ws = ws; break; + } ++ws; } if (i == info->win_size_num) @@ -172,6 +176,7 @@ static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd, for (i = 0; i < info->win_size_num; ++i) { if ((ws->fps_fixed == info->tpf.denominator) && (ws->wdr_mode == ISP_COMANDING_MODE)) { + best_ws = ws; fps_flag = 1; break; } @@ -181,6 +186,7 @@ static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd, for (i = 0; i < info->win_size_num; ++i) { if ((ws->fps_fixed == info->tpf.denominator) && (ws->wdr_mode == ISP_DOL_WDR_MODE)) { + best_ws = ws; fps_flag = 1; break; } @@ -190,6 +196,7 @@ static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd, for (i = 0; i < info->win_size_num; ++i) { if ((ws->fps_fixed == info->tpf.denominator) && (ws->wdr_mode == ISP_NORMAL_MODE)) { + best_ws = ws; fps_flag = 1; break; } diff --git a/drivers/media/platform/sunxi-vin/modules/sensor/sensor_ptn.c b/drivers/media/platform/sunxi-vin/modules/sensor/sensor_ptn.c index 0cf9a614..47abcef4 100644 --- a/drivers/media/platform/sunxi-vin/modules/sensor/sensor_ptn.c +++ b/drivers/media/platform/sunxi-vin/modules/sensor/sensor_ptn.c @@ -25,7 +25,7 @@ #include "camera.h" #include "sensor_helper.h" -MODULE_AUTHOR("lwj"); +MODULE_AUTHOR("zw"); MODULE_DESCRIPTION("A low-level driver for pattern sensors"); MODULE_LICENSE("GPL"); @@ -58,10 +58,6 @@ static struct regval_list sensor_default_regs[] = { }; -static struct regval_list sensor_1080p30_regs[] = { - -}; - /* * Here we'll try to encapsulate the changes for just the output * video format. @@ -106,98 +102,16 @@ static int sensor_s_exp_gain(struct v4l2_subdev *sd, return 0; } -static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) -{ - return 0; -} - /* * Stuff that knows about the sensor. */ static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret = 0; - - switch (on) { - case STBY_ON: - sensor_dbg("STBY_ON!\n"); - cci_lock(sd); - ret = sensor_s_sw_stby(sd, STBY_ON); - if (ret < 0) - sensor_err("soft stby falied!\n"); - usleep_range(1000, 1200); - cci_unlock(sd); - break; - case STBY_OFF: - sensor_dbg("STBY_OFF!\n"); - cci_lock(sd); - usleep_range(1000, 1200); - ret = sensor_s_sw_stby(sd, STBY_OFF); - if (ret < 0) - sensor_err("soft stby off falied!\n"); - cci_unlock(sd); - break; - case PWR_ON: - sensor_dbg("PWR_ON!\n"); - cci_lock(sd); - vin_gpio_set_status(sd, PWDN, 1); - vin_gpio_set_status(sd, RESET, 1); - vin_gpio_set_status(sd, POWER_EN, 1); - vin_gpio_write(sd, RESET, CSI_GPIO_LOW); - vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); - vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH); - vin_set_pmu_channel(sd, IOVDD, ON); - usleep_range(2000, 2200); - vin_set_pmu_channel(sd, DVDD, ON); - vin_set_pmu_channel(sd, AVDD, ON); - vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); - vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH); - usleep_range(100, 120); - vin_set_mclk(sd, ON); - usleep_range(100, 120); - vin_set_mclk_freq(sd, MCLK); - usleep_range(3000, 3200); - cci_unlock(sd); - break; - case PWR_OFF: - sensor_dbg("PWR_OFF!\n"); - cci_lock(sd); - vin_gpio_set_status(sd, PWDN, 1); - vin_gpio_set_status(sd, RESET, 1); - vin_gpio_write(sd, RESET, CSI_GPIO_LOW); - vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); - vin_set_mclk(sd, OFF); - vin_set_pmu_channel(sd, AFVDD, OFF); - vin_set_pmu_channel(sd, AVDD, OFF); - vin_set_pmu_channel(sd, IOVDD, OFF); - vin_set_pmu_channel(sd, DVDD, OFF); - vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW); - vin_gpio_set_status(sd, RESET, 0); - vin_gpio_set_status(sd, PWDN, 0); - vin_gpio_set_status(sd, POWER_EN, 0); - cci_unlock(sd); - break; - default: - return -EINVAL; - } - return 0; } static int sensor_reset(struct v4l2_subdev *sd, u32 val) { - switch (val) { - case 0: - vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); - usleep_range(100, 120); - break; - case 1: - vin_gpio_write(sd, RESET, CSI_GPIO_LOW); - usleep_range(100, 120); - break; - default: - return -EINVAL; - } return 0; } @@ -284,14 +198,185 @@ static struct sensor_format_struct sensor_formats[] = { */ static struct sensor_win_size sensor_win_sizes[] = { - { + { + .width = 4224, + .height = 128, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 3840, + .height = 256, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 3264, + .height = 256, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 2688, + .height = 128, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 1920, + .height = 1088, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { .width = 1920, .height = 1080, .hoffset = 0, .voffset = 0, .hts = 2288, .vts = 8400, - .pclk = 576 * 1000 * 1000, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 1920, + .height = 256, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 1920, + .height = 128, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 1024, + .height = 128, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, + .mipi_bps = 720 * 1000 * 1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 4 << 4, + .intg_max = (4200 - 12) << 4, + .gain_min = 1 << 4, + .gain_max = 1440 << 4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + { + .width = 256, + .height = 128, + .hoffset = 0, + .voffset = 0, + .hts = 2288, + .vts = 8400, + .pclk = 288 * 1000 * 1000, .mipi_bps = 720 * 1000 * 1000, .fps_fixed = 30, .bin_factor = 1, @@ -299,8 +384,8 @@ static struct sensor_win_size sensor_win_sizes[] = { .intg_max = (4200 - 12) << 4, .gain_min = 1 << 4, .gain_max = 1440 << 4, - .regs = sensor_1080p30_regs, - .regs_size = ARRAY_SIZE(sensor_1080p30_regs), + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), .set_size = NULL, }, }; @@ -490,7 +575,6 @@ static int sensor_probe(struct i2c_client *client, info->fmt_num = N_FMTS; info->win_size_num = N_WIN_SIZES; info->sensor_field = V4L2_FIELD_NONE; - info->combo_mode = CMB_TERMINAL_RES | CMB_PHYA_OFFSET3 | MIPI_NORMAL_MODE; info->stream_seq = MIPI_BEFORE_SENSOR; info->af_first_flag = 1; info->exp = 0; diff --git a/drivers/media/platform/sunxi-vin/platform/platform_cfg.h b/drivers/media/platform/sunxi-vin/platform/platform_cfg.h index 6fd2294e..1190b280 100644 --- a/drivers/media/platform/sunxi-vin/platform/platform_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/platform_cfg.h @@ -47,26 +47,27 @@ #if defined CONFIG_ARCH_SUN50IW1P1 #include "sun50iw1p1_vfe_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_SUN50IW1P1 #elif defined CONFIG_ARCH_SUN8IW11P1 #include "sun8iw11p1_vfe_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_NUM #elif defined CONFIG_ARCH_SUN50IW3P1 #include "sun50iw3p1_vin_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_NUM #define CROP_AFTER_SCALER #elif defined CONFIG_ARCH_SUN50IW6P1 #include "sun50iw6p1_vin_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_NUM #define CROP_AFTER_SCALER #elif defined CONFIG_ARCH_SUN8IW12P1 #include "sun8iw12p1_vin_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_SUN8IW12P1 #elif defined CONFIG_ARCH_SUN8IW17P1 -#include "sun8iw17p1_vin_cfg.h" -#define SUNXI_PLATFORM_ID ISP_PLATFORM_SUN8IW17P1 +#include "sun8iw12p1_vin_cfg.h" #endif +#define ALIGN_4K(x) (((x) + (4095)) & ~(4095)) +#define ALIGN_32B(x) (((x) + (31)) & ~(31)) +#define ALIGN_16B(x) (((x) + (15)) & ~(15)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define CLIP(a, i, s) (((a) > (s)) ? (s) : MAX(a, i)) + struct mbus_framefmt_res { u32 res_pix_fmt; u32 res_mipi_bps; diff --git a/drivers/media/platform/sunxi-vin/platform/sun50iw1p1_vfe_cfg.h b/drivers/media/platform/sunxi-vin/platform/sun50iw1p1_vfe_cfg.h index b2688f93..3aea473b 100644 --- a/drivers/media/platform/sunxi-vin/platform/sun50iw1p1_vfe_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/sun50iw1p1_vfe_cfg.h @@ -23,9 +23,6 @@ #define MIPI_CSI0_REGS_BASE 0x01cb1000 #define ISP_REGS_BASE 0x01cb8000 -#define GPIO_REGS_VBASE 0x01c20800 -#define CPU_DRAM_PADDR_ORG 0x40000000 -#define HW_DMA_OFFSET 0x00000000 /*set vin core clk base on sensor size*/ #define CORE_CLK_RATE_FOR_2M (108*1000*1000) @@ -42,66 +39,6 @@ #define CSI0_CCI_REG_SIZE 0x1000 #define CSI1_REG_SIZE 0x1000 #define CSI1_CCI_REG_SIZE 0x1000 -#define ISP_REG_SIZE 0x1000 -#define ISP_LOAD_REG_SIZE 0x1000 -#define ISP_SAVED_REG_SIZE 0x1000 - -/*ISP size configs*/ - -/*stat size configs*/ - -#define ISP_STAT_TOTAL_SIZE 0xAB00 - -#define ISP_STAT_HIST_MEM_SIZE 0x0200 -#define ISP_STAT_AE_MEM_SIZE 0x4800 -#define ISP_STAT_AF_MEM_SIZE 0x0500 -#define ISP_STAT_AFS_MEM_SIZE 0x0200 -#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 -#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 -#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 - -#define ISP_STAT_HIST_MEM_OFS 0x0000 -#define ISP_STAT_AE_MEM_OFS 0x0200 -#define ISP_STAT_AF_MEM_OFS 0x4a00 -#define ISP_STAT_AFS_MEM_OFS 0x4f00 -#define ISP_STAT_AWB_MEM_OFS 0x5100 -#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 - -/*table size configs*/ - -#define ISP_TABLE_MAPPING1_SIZE 0x5a00 -#define ISP_LSC_MEM_SIZE (256*8) -#define ISP_GAMMA_MEM_SIZE (256*4) -#define ISP_LINEAR_MEM_SIZE (256*6) -#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) -#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) -#define ISP_TDNF_DIFF_MEM_SIZE (256*1) -#define ISP_PLTM_H_MEM_SIZE (256*1) -#define ISP_PLTM_V_MEM_SIZE (256*1) -#define ISP_PLTM_POW_MEM_SIZE (256*2) -#define ISP_PLTM_F_MEM_SIZE (256*2) -#define ISP_CONTRAST_PE_MEM_SIZE (128*2) - -#define ISP_TABLE_MAPPING2_SIZE 0x1f00 -#define ISP_DRC_MEM_SIZE (256*2) -#define ISP_SATURATION_MEM_SIZE (256*2) -#define ISP_CEM_MEM_SIZE (736*8) - -#define ISP_LSC_MEM_OFS 0x0 -#define ISP_GAMMA_MEM_OFS 0x0800 -#define ISP_LINEAR_MEM_OFS 0x0c00 -#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 -#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 -#define ISP_TDNF_DIFF_MEM_OFS 0x5200 -#define ISP_PLTM_H_MEM_OFS 0x5300 -#define ISP_PLTM_V_MEM_OFS 0x5400 -#define ISP_PLTM_POW_MEM_OFS 0x5500 -#define ISP_PLTM_F_MEM_OFS 0x5700 -#define ISP_CONTRAST_PE_MEM_OFS 0x5900 - -#define ISP_DRC_MEM_OFS 0x0 -#define ISP_SATURATION_MEM_OFS 0x0600 -#define ISP_CEM_MEM_OFS 0x0800 #define VIN_MAX_DEV 1 #define VIN_MAX_CSI 1 diff --git a/drivers/media/platform/sunxi-vin/platform/sun50iw3p1_vin_cfg.h b/drivers/media/platform/sunxi-vin/platform/sun50iw3p1_vin_cfg.h index efe7badf..e5cce964 100644 --- a/drivers/media/platform/sunxi-vin/platform/sun50iw3p1_vin_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/sun50iw3p1_vin_cfg.h @@ -1,20 +1,17 @@ /* - ****************************************************************************** + * Hawkview ISP - sun50iw3p1_vin_cfg.h module * - * sun50iw1p1_vfe_cfg.h + * Copyright (c) 2018 by Allwinnertech Co., Ltd. http://www.allwinnertech.com * - * Hawkview ISP - sun50iw1p1_vfe_cfg.h module + * Authors: Zhao Wei * - * Copyright (c) 2014 by Allwinnertech Co., Ltd. http://www.allwinnertech.com - * - * Version Author Date Description - * - * 2.0 Yang Feng 2014/07/24 Second Version - * - ****************************************************************************** + * 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. */ + #ifndef _SUN50IW3P1_VIN_CFG_H_ #define _SUN50IW3P1_VIN_CFG_H_ @@ -44,69 +41,9 @@ #define CSI0_CCI_REG_SIZE 0x1000 #define CSI1_REG_SIZE 0x1000 #define CSI1_CCI_REG_SIZE 0x1000 -#define ISP_REG_SIZE 0x1000 -#define ISP_LOAD_REG_SIZE 0x1000 -#define ISP_SAVED_REG_SIZE 0x1000 #define VIPP0_REG_SIZE 0x400 #define VIPP1_REG_SIZE 0x400 -/*ISP size configs*/ - -/*stat size configs*/ - -#define ISP_STAT_TOTAL_SIZE 0xAB00 - -#define ISP_STAT_HIST_MEM_SIZE 0x0200 -#define ISP_STAT_AE_MEM_SIZE 0x4800 -#define ISP_STAT_AF_MEM_SIZE 0x0500 -#define ISP_STAT_AFS_MEM_SIZE 0x0200 -#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 -#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 -#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 - -#define ISP_STAT_HIST_MEM_OFS 0x0000 -#define ISP_STAT_AE_MEM_OFS 0x0200 -#define ISP_STAT_AF_MEM_OFS 0x4a00 -#define ISP_STAT_AFS_MEM_OFS 0x4f00 -#define ISP_STAT_AWB_MEM_OFS 0x5100 -#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 - -/*table size configs*/ - -#define ISP_TABLE_MAPPING1_SIZE 0x5a00 -#define ISP_LSC_MEM_SIZE (256*8) -#define ISP_GAMMA_MEM_SIZE (256*4) -#define ISP_LINEAR_MEM_SIZE (256*6) -#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) -#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) -#define ISP_TDNF_DIFF_MEM_SIZE (256*1) -#define ISP_PLTM_H_MEM_SIZE (256*1) -#define ISP_PLTM_V_MEM_SIZE (256*1) -#define ISP_PLTM_POW_MEM_SIZE (256*2) -#define ISP_PLTM_F_MEM_SIZE (256*2) -#define ISP_CONTRAST_PE_MEM_SIZE (128*2) - -#define ISP_TABLE_MAPPING2_SIZE 0x1f00 -#define ISP_DRC_MEM_SIZE (256*2) -#define ISP_SATURATION_MEM_SIZE (256*2) -#define ISP_CEM_MEM_SIZE (736*8) - -#define ISP_LSC_MEM_OFS 0x0 -#define ISP_GAMMA_MEM_OFS 0x0800 -#define ISP_LINEAR_MEM_OFS 0x0c00 -#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 -#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 -#define ISP_TDNF_DIFF_MEM_OFS 0x5200 -#define ISP_PLTM_H_MEM_OFS 0x5300 -#define ISP_PLTM_V_MEM_OFS 0x5400 -#define ISP_PLTM_POW_MEM_OFS 0x5500 -#define ISP_PLTM_F_MEM_OFS 0x5700 -#define ISP_CONTRAST_PE_MEM_OFS 0x5900 - -#define ISP_DRC_MEM_OFS 0x0 -#define ISP_SATURATION_MEM_OFS 0x0600 -#define ISP_CEM_MEM_OFS 0x0800 - #define VIN_MAX_DEV 2 #define VIN_MAX_CSI 1 #define VIN_MAX_CCI 1 diff --git a/drivers/media/platform/sunxi-vin/platform/sun50iw6p1_vin_cfg.h b/drivers/media/platform/sunxi-vin/platform/sun50iw6p1_vin_cfg.h index 4812cc94..f5f42f79 100644 --- a/drivers/media/platform/sunxi-vin/platform/sun50iw6p1_vin_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/sun50iw6p1_vin_cfg.h @@ -1,18 +1,14 @@ /* - ****************************************************************************** + * Hawkview ISP - sun50iw6p1_vin_cfg.h module * - * sun50iw1p1_vfe_cfg.h + * Copyright (c) 2018 by Allwinnertech Co., Ltd. http://www.allwinnertech.com * - * Hawkview ISP - sun50iw1p1_vfe_cfg.h module + * Authors: Zhao Wei * - * Copyright (c) 2014 by Allwinnertech Co., Ltd. http://www.allwinnertech.com - * - * Version Author Date Description - * - * 2.0 Yang Feng 2014/07/24 Second Version - * - ****************************************************************************** + * 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. */ #ifndef _SUN50IW6P1_VIN_CFG_H_ @@ -44,69 +40,9 @@ #define CSI0_CCI_REG_SIZE 0x1000 #define CSI1_REG_SIZE 0x1000 #define CSI1_CCI_REG_SIZE 0x1000 -#define ISP_REG_SIZE 0x1000 -#define ISP_LOAD_REG_SIZE 0x1000 -#define ISP_SAVED_REG_SIZE 0x1000 #define VIPP0_REG_SIZE 0x400 #define VIPP1_REG_SIZE 0x400 -/*ISP size configs*/ - -/*stat size configs*/ - -#define ISP_STAT_TOTAL_SIZE 0xAB00 - -#define ISP_STAT_HIST_MEM_SIZE 0x0200 -#define ISP_STAT_AE_MEM_SIZE 0x4800 -#define ISP_STAT_AF_MEM_SIZE 0x0500 -#define ISP_STAT_AFS_MEM_SIZE 0x0200 -#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 -#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 -#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 - -#define ISP_STAT_HIST_MEM_OFS 0x0000 -#define ISP_STAT_AE_MEM_OFS 0x0200 -#define ISP_STAT_AF_MEM_OFS 0x4a00 -#define ISP_STAT_AFS_MEM_OFS 0x4f00 -#define ISP_STAT_AWB_MEM_OFS 0x5100 -#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 - -/*table size configs*/ - -#define ISP_TABLE_MAPPING1_SIZE 0x5a00 -#define ISP_LSC_MEM_SIZE (256*8) -#define ISP_GAMMA_MEM_SIZE (256*4) -#define ISP_LINEAR_MEM_SIZE (256*6) -#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) -#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) -#define ISP_TDNF_DIFF_MEM_SIZE (256*1) -#define ISP_PLTM_H_MEM_SIZE (256*1) -#define ISP_PLTM_V_MEM_SIZE (256*1) -#define ISP_PLTM_POW_MEM_SIZE (256*2) -#define ISP_PLTM_F_MEM_SIZE (256*2) -#define ISP_CONTRAST_PE_MEM_SIZE (128*2) - -#define ISP_TABLE_MAPPING2_SIZE 0x1f00 -#define ISP_DRC_MEM_SIZE (256*2) -#define ISP_SATURATION_MEM_SIZE (256*2) -#define ISP_CEM_MEM_SIZE (736*8) - -#define ISP_LSC_MEM_OFS 0x0 -#define ISP_GAMMA_MEM_OFS 0x0800 -#define ISP_LINEAR_MEM_OFS 0x0c00 -#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 -#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 -#define ISP_TDNF_DIFF_MEM_OFS 0x5200 -#define ISP_PLTM_H_MEM_OFS 0x5300 -#define ISP_PLTM_V_MEM_OFS 0x5400 -#define ISP_PLTM_POW_MEM_OFS 0x5500 -#define ISP_PLTM_F_MEM_OFS 0x5700 -#define ISP_CONTRAST_PE_MEM_OFS 0x5900 - -#define ISP_DRC_MEM_OFS 0x0 -#define ISP_SATURATION_MEM_OFS 0x0600 -#define ISP_CEM_MEM_OFS 0x0800 - #define VIN_MAX_DEV 2 #define VIN_MAX_CSI 1 #define VIN_MAX_CCI 1 diff --git a/drivers/media/platform/sunxi-vin/platform/sun8iw11p1_vfe_cfg.h b/drivers/media/platform/sunxi-vin/platform/sun8iw11p1_vfe_cfg.h index 9a47a124..a17256eb 100644 --- a/drivers/media/platform/sunxi-vin/platform/sun8iw11p1_vfe_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/sun8iw11p1_vfe_cfg.h @@ -23,9 +23,6 @@ #define MIPI_CSI0_REGS_BASE 0x01cb1000 #define ISP_REGS_BASE 0x01cb8000 -#define GPIO_REGS_VBASE 0x01c20800 -#define CPU_DRAM_PADDR_ORG 0x40000000 -#define HW_DMA_OFFSET 0x00000000 /*set vin core clk base on sensor size*/ #define CORE_CLK_RATE_FOR_2M (108*1000*1000) @@ -42,66 +39,6 @@ #define CSI0_CCI_REG_SIZE 0x1000 #define CSI1_REG_SIZE 0x1000 #define CSI1_CCI_REG_SIZE 0x1000 -#define ISP_REG_SIZE 0x1000 -#define ISP_LOAD_REG_SIZE 0x1000 -#define ISP_SAVED_REG_SIZE 0x1000 - -/*ISP size configs*/ - -/*stat size configs*/ - -#define ISP_STAT_TOTAL_SIZE 0xAB00 - -#define ISP_STAT_HIST_MEM_SIZE 0x0200 -#define ISP_STAT_AE_MEM_SIZE 0x4800 -#define ISP_STAT_AF_MEM_SIZE 0x0500 -#define ISP_STAT_AFS_MEM_SIZE 0x0200 -#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 -#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 -#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 - -#define ISP_STAT_HIST_MEM_OFS 0x0000 -#define ISP_STAT_AE_MEM_OFS 0x0200 -#define ISP_STAT_AF_MEM_OFS 0x4a00 -#define ISP_STAT_AFS_MEM_OFS 0x4f00 -#define ISP_STAT_AWB_MEM_OFS 0x5100 -#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 - -/*table size configs*/ - -#define ISP_TABLE_MAPPING1_SIZE 0x5a00 -#define ISP_LSC_MEM_SIZE (256*8) -#define ISP_GAMMA_MEM_SIZE (256*4) -#define ISP_LINEAR_MEM_SIZE (256*6) -#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) -#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) -#define ISP_TDNF_DIFF_MEM_SIZE (256*1) -#define ISP_PLTM_H_MEM_SIZE (256*1) -#define ISP_PLTM_V_MEM_SIZE (256*1) -#define ISP_PLTM_POW_MEM_SIZE (256*2) -#define ISP_PLTM_F_MEM_SIZE (256*2) -#define ISP_CONTRAST_PE_MEM_SIZE (128*2) - -#define ISP_TABLE_MAPPING2_SIZE 0x1f00 -#define ISP_DRC_MEM_SIZE (256*2) -#define ISP_SATURATION_MEM_SIZE (256*2) -#define ISP_CEM_MEM_SIZE (736*8) - -#define ISP_LSC_MEM_OFS 0x0 -#define ISP_GAMMA_MEM_OFS 0x0800 -#define ISP_LINEAR_MEM_OFS 0x0c00 -#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 -#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 -#define ISP_TDNF_DIFF_MEM_OFS 0x5200 -#define ISP_PLTM_H_MEM_OFS 0x5300 -#define ISP_PLTM_V_MEM_OFS 0x5400 -#define ISP_PLTM_POW_MEM_OFS 0x5500 -#define ISP_PLTM_F_MEM_OFS 0x5700 -#define ISP_CONTRAST_PE_MEM_OFS 0x5900 - -#define ISP_DRC_MEM_OFS 0x0 -#define ISP_SATURATION_MEM_OFS 0x0600 -#define ISP_CEM_MEM_OFS 0x0800 #define VIN_MAX_DEV 2 #define VIN_MAX_CSI 2 diff --git a/drivers/media/platform/sunxi-vin/platform/sun8iw12p1_vin_cfg.h b/drivers/media/platform/sunxi-vin/platform/sun8iw12p1_vin_cfg.h index 54e04f42..c130dbca 100644 --- a/drivers/media/platform/sunxi-vin/platform/sun8iw12p1_vin_cfg.h +++ b/drivers/media/platform/sunxi-vin/platform/sun8iw12p1_vin_cfg.h @@ -59,67 +59,6 @@ #define MIPI_CSI2_REG_SIZE 0x1000 #define MIPI_DPHY_REG_SIZE 0x1000 -#define ISP_REG_SIZE 0x400 -#define ISP_LOAD_REG_SIZE 0x400 -#define ISP_SAVED_REG_SIZE 0x400 - -/*ISP size configs*/ - -/*stat size configs*/ - -#define ISP_STAT_TOTAL_SIZE 0xAB00 - -#define ISP_STAT_HIST_MEM_SIZE 0x0200 -#define ISP_STAT_AE_MEM_SIZE 0x4800 -#define ISP_STAT_AF_MEM_SIZE 0x0500 -#define ISP_STAT_AFS_MEM_SIZE 0x0200 -#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 -#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 -#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 - -#define ISP_STAT_HIST_MEM_OFS 0x0000 -#define ISP_STAT_AE_MEM_OFS 0x0200 -#define ISP_STAT_AF_MEM_OFS 0x4a00 -#define ISP_STAT_AFS_MEM_OFS 0x4f00 -#define ISP_STAT_AWB_MEM_OFS 0x5100 -#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 - -/*table size configs*/ - -#define ISP_TABLE_MAPPING1_SIZE 0x5a00 -#define ISP_LSC_MEM_SIZE (256*8) -#define ISP_GAMMA_MEM_SIZE (256*4) -#define ISP_LINEAR_MEM_SIZE (256*6) -#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) -#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) -#define ISP_TDNF_DIFF_MEM_SIZE (256*1) -#define ISP_PLTM_H_MEM_SIZE (256*1) -#define ISP_PLTM_V_MEM_SIZE (256*1) -#define ISP_PLTM_POW_MEM_SIZE (256*2) -#define ISP_PLTM_F_MEM_SIZE (256*2) -#define ISP_CONTRAST_PE_MEM_SIZE (128*2) - -#define ISP_TABLE_MAPPING2_SIZE 0x1f00 -#define ISP_DRC_MEM_SIZE (256*2) -#define ISP_SATURATION_MEM_SIZE (256*2) -#define ISP_CEM_MEM_SIZE (736*8) - -#define ISP_LSC_MEM_OFS 0x0 -#define ISP_GAMMA_MEM_OFS 0x0800 -#define ISP_LINEAR_MEM_OFS 0x0c00 -#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 -#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 -#define ISP_TDNF_DIFF_MEM_OFS 0x5200 -#define ISP_PLTM_H_MEM_OFS 0x5300 -#define ISP_PLTM_V_MEM_OFS 0x5400 -#define ISP_PLTM_POW_MEM_OFS 0x5500 -#define ISP_PLTM_F_MEM_OFS 0x5700 -#define ISP_CONTRAST_PE_MEM_OFS 0x5900 - -#define ISP_DRC_MEM_OFS 0x0 -#define ISP_SATURATION_MEM_OFS 0x0600 -#define ISP_CEM_MEM_OFS 0x0800 - #define VIN_MAX_DEV 8 #define VIN_MAX_CSI 4 #define VIN_MAX_CCI 4 diff --git a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.c b/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.c deleted file mode 100644 index 2cf72548..00000000 --- a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.c +++ /dev/null @@ -1,198 +0,0 @@ - -/* - ****************************************************************************** - * - * bsp_isp.c - * - * Hawkview ISP - bsp_isp.c module - * - * Copyright (c) 2013 by Allwinnertech Co., Ltd. http: - * - * Version Author Date Description - * - * 1.0 Yang Feng 2013/11/07 First Version - * - ****************************************************************************** - */ - -#include -#include - -#include "bsp_isp.h" -#include "isp_platform_drv.h" -#include "bsp_isp_comm.h" - -static int isp_platform_id; -struct isp_bsp_fun_array *fun_array_curr; - -void bsp_isp_enable(unsigned long id) -{ - fun_array_curr->isp_enable(id, 1); -} - -void bsp_isp_disable(unsigned long id) -{ - fun_array_curr->isp_enable(id, 0); -} - -void bsp_isp_channel_enable(unsigned long id, enum isp_channel ch) -{ - fun_array_curr->isp_ch_enable(id, ch, 1); -} - -void bsp_isp_channel_disable(unsigned long id, enum isp_channel ch) -{ - fun_array_curr->isp_ch_enable(id, ch, 0); -} - -void bsp_isp_capture_start(unsigned long id) -{ - fun_array_curr->isp_capture_start(id); -} - -void bsp_isp_capture_stop(unsigned long id) -{ - fun_array_curr->isp_capture_stop(id); -} - -unsigned int bsp_isp_get_para_ready(unsigned long id) -{ - return fun_array_curr->isp_get_para_ready(id); -} - -void bsp_isp_set_para_ready(unsigned long id) -{ - fun_array_curr->isp_set_para_ready(id, PARA_READY); -} -void bsp_isp_clr_para_ready(unsigned long id) -{ - fun_array_curr->isp_set_para_ready(id, PARA_NOT_READY); -} - -void bsp_isp_irq_enable(unsigned long id, unsigned int irq_flag) -{ - fun_array_curr->isp_irq_enable(id, irq_flag); -} -void bsp_isp_irq_disable(unsigned long id, unsigned int irq_flag) -{ - fun_array_curr->isp_irq_disable(id, irq_flag); -} - -unsigned int bsp_isp_get_irq_status(unsigned long id, unsigned int irq) -{ - return fun_array_curr->isp_get_irq_status(id, irq); -} - - -void bsp_isp_clr_irq_status(unsigned long id, unsigned int irq) -{ - fun_array_curr->isp_clr_irq_status(id, irq); -} - -int bsp_isp_int_get_enable(unsigned long id) -{ - return fun_array_curr->isp_int_get_enable(id); -} - -void bsp_isp_debug_output_cfg(unsigned long id, int enable, int sel) -{ - fun_array_curr->isp_debug_output_cfg(id, enable, sel); -} - -void bsp_isp_set_statistics_addr(unsigned long id, dma_addr_t addr) -{ - fun_array_curr->isp_set_statistics_addr(id, addr); -} - -void bsp_isp_set_base_addr(unsigned long id, unsigned long vaddr) -{ - fun_array_curr->map_reg_addr(id, vaddr); -} - -void bsp_isp_set_dma_load_addr(unsigned long id, unsigned long dma_addr) -{ - fun_array_curr->isp_set_load_addr(id, dma_addr); -} - -void bsp_isp_set_dma_saved_addr(unsigned long id, unsigned long dma_addr) -{ - fun_array_curr->isp_set_saved_addr(id, dma_addr); -} - -void bsp_isp_set_map_load_addr(unsigned long id, unsigned long vaddr) -{ - fun_array_curr->map_load_dram_addr(id, vaddr); -} - -void bsp_isp_set_map_saved_addr(unsigned long id, unsigned long vaddr) -{ - fun_array_curr->map_saved_dram_addr(id, vaddr); -} - -void bsp_isp_update_lens_gamma_table(unsigned long id, struct isp_table_addr *tbl_addr) -{ - fun_array_curr->isp_set_table_addr(id, LENS_GAMMA_TABLE, - (unsigned long)(tbl_addr->isp_lsc_tbl_dma_addr)); -} - -void bsp_isp_update_drc_table(unsigned long id, struct isp_table_addr *tbl_addr) -{ - fun_array_curr->isp_set_table_addr(id, DRC_TABLE, - (unsigned long)(tbl_addr->isp_drc_tbl_dma_addr)); -} - -void bsp_isp_update_table(unsigned long id, unsigned short flag) -{ - fun_array_curr->isp_update_table(id, flag); -} - -void bsp_isp_set_speed_mode(unsigned long id, unsigned int speed_mode) -{ - fun_array_curr->isp_set_speed_mode(id, speed_mode); -} - -void bsp_isp_set_last_blank_cycle(unsigned long id, unsigned int last_blank_cycle) -{ - fun_array_curr->isp_set_last_blank_cycle(id, last_blank_cycle); -} - -void bsp_isp_module_enable(unsigned long id, unsigned int modules) -{ - fun_array_curr->isp_module_enable(id, modules); -} - -void bsp_isp_module_disable(unsigned long id, unsigned int modules) -{ - fun_array_curr->isp_module_disable(id, modules); -} - -void bsp_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode) -{ - fun_array_curr->isp_set_wdr_mode(id, wdr_mode); -} - -void bsp_isp_set_input_fmt(unsigned long id, enum isp_input_seq fmt) -{ - fun_array_curr->isp_set_input_fmt(id, (unsigned int)fmt); -} - -void bsp_isp_set_ob_zone(unsigned long id, struct isp_size_settings *ss) -{ - fun_array_curr->isp_set_size(id, &ss->ob_black, &ss->ob_valid, &ss->ob_start); -} - -unsigned int bsp_isp_load_update_flag(unsigned long id) -{ - return fun_array_curr->isp_load_update_flag(id); -} - -void bsp_isp_init_platform(unsigned int platform_id) -{ - struct isp_platform_drv *isp_platform; - - - isp_platform_id = platform_id; - isp_platform_init(platform_id); - isp_platform = isp_get_driver(); - fun_array_curr = isp_platform->fun_array; -} diff --git a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.h b/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.h deleted file mode 100644 index 70887204..00000000 --- a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp.h +++ /dev/null @@ -1,86 +0,0 @@ - -/* - ***************************************************************************** - * - * bsp_isp.h - * - * Hawkview ISP - bsp_isp.h module - * - * Copyright (c) 2013 by Allwinnertech Co., Ltd. http: - * - * Version Author Date Description - * - * 1.0 Yang Feng 2013/12/25 First Version - * - ****************************************************************************** - */ -#ifndef __BSP__ISP__H -#define __BSP__ISP__H - -#include "../utility/bsp_common.h" -#include "bsp_isp_comm.h" - -struct isp_table_addr { - void *isp_lsc_tbl_vaddr; - void *isp_lsc_tbl_paddr; - void *isp_lsc_tbl_dma_addr; - void *isp_gamma_tbl_vaddr; - void *isp_gamma_tbl_paddr; - void *isp_gamma_tbl_dma_addr; - void *isp_linear_tbl_vaddr; - void *isp_linear_tbl_paddr; - void *isp_linear_tbl_dma_addr; - - void *isp_drc_tbl_vaddr; - void *isp_drc_tbl_paddr; - void *isp_drc_tbl_dma_addr; - void *isp_saturation_tbl_vaddr; - void *isp_saturation_tbl_paddr; - void *isp_saturation_tbl_dma_addr; -}; - -void bsp_isp_enable(unsigned long id); -void bsp_isp_disable(unsigned long id); - -void bsp_isp_channel_enable(unsigned long id, enum isp_channel ch); -void bsp_isp_channel_disable(unsigned long id, enum isp_channel ch); - -void bsp_isp_capture_start(unsigned long id); -void bsp_isp_capture_stop(unsigned long id); -unsigned int bsp_isp_get_para_ready(unsigned long id); -void bsp_isp_set_para_ready(unsigned long id); -void bsp_isp_clr_para_ready(unsigned long id); - -void bsp_isp_irq_enable(unsigned long id, unsigned int irq_flag); -void bsp_isp_irq_disable(unsigned long id, unsigned int irq_flag); -unsigned int bsp_isp_get_irq_status(unsigned long id, unsigned int irq); -int bsp_isp_int_get_enable(unsigned long id); - -void bsp_isp_clr_irq_status(unsigned long id, unsigned int irq); - -void bsp_isp_debug_output_cfg(unsigned long id, int enable, int sel); - -void bsp_isp_set_statistics_addr(unsigned long id, dma_addr_t addr); -void bsp_isp_set_last_blank_cycle(unsigned long id, unsigned int last_blank_cycle); -void bsp_isp_set_speed_mode(unsigned long id, unsigned int speed_mode); - -void bsp_isp_module_enable(unsigned long id, unsigned int modules); -void bsp_isp_module_disable(unsigned long id, unsigned int modules); - -void bsp_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode); -void bsp_isp_set_input_fmt(unsigned long id, enum isp_input_seq fmt); -void bsp_isp_set_ob_zone(unsigned long id, struct isp_size_settings *ss); - -void bsp_isp_set_base_addr(unsigned long id, unsigned long vaddr); -void bsp_isp_set_dma_load_addr(unsigned long id, unsigned long dma_addr); -void bsp_isp_set_dma_saved_addr(unsigned long id, unsigned long dma_addr); -void bsp_isp_set_map_load_addr(unsigned long id, unsigned long vaddr); -void bsp_isp_set_map_saved_addr(unsigned long id, unsigned long vaddr); -void bsp_isp_update_lens_gamma_table(unsigned long id, struct isp_table_addr *tbl_addr); -void bsp_isp_update_drc_table(unsigned long id, struct isp_table_addr *tbl_addr); -void bsp_isp_update_table(unsigned long id, unsigned short flag); -unsigned int bsp_isp_load_update_flag(unsigned long id); - -void bsp_isp_init_platform(unsigned int platform_id); - -#endif diff --git a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp_comm.h b/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp_comm.h deleted file mode 100644 index 55b14d17..00000000 --- a/drivers/media/platform/sunxi-vin/vin-isp/bsp_isp_comm.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * bsp_isp_comm.h - * - * Copyright (c) 2007-2017 Allwinnertech Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#ifndef __BSP__ISP__COMM__H -#define __BSP__ISP__COMM__H - -#define ALIGN_4K(x) (((x) + (4095)) & ~(4095)) -#define ALIGN_32B(x) (((x) + (31)) & ~(31)) -#define ALIGN_16B(x) (((x) + (15)) & ~(15)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define CLIP(a, i, s) (((a) > (s)) ? (s) : MAX(a, i)) - -enum isp_platform { - ISP_PLATFORM_SUN8IW12P1, - ISP_PLATFORM_SUN8IW17P1, - - ISP_PLATFORM_NUM, -}; -/* - * update table - */ -#define LUT_UPDATE (1 << 3) -#define LINEAR_UPDATE (1 << 3) -#define LENS_UPDATE (1 << 4) -#define GAMMA_UPDATE (1 << 5) -#define DRC_UPDATE (1 << 6) -#define DISC_UPDATE (1 << 7) -#define SATU_UPDATE (1 << 8) -#define WDR_UPDATE (1 << 9) -#define TDNF_UPDATE (1 << 10) -#define PLTM_UPDATE (1 << 11) -#define CEM_UPDATE (1 << 12) -#define CONTRAST_UPDATE (1 << 13) - -#define TABLE_UPDATE_ALL 0xffffffff - -/* - * ISP Module enable - */ -#define AE_EN (1 << 0) -#define LC_EN (1 << 1) -#define WDR_EN (1 << 2) -#define OTF_DPC_EN (1 << 3) -#define BDNF_EN (1 << 4) -#define TDNF_EN (1 << 5) -#define AWB_EN (1 << 6) -#define WB_EN (1 << 7) -#define LSC_EN (1 << 8) -#define BGC_EN (1 << 9) -#define SAP_EN (1 << 10) -#define AF_EN (1 << 11) -#define RGB2RGB_EN (1 << 12) -#define RGB_DRC_EN (1 << 13) -#define PLTM_EN (1 << 14) -#define CEM_EN (1 << 15) -#define AFS_EN (1 << 16) -#define HIST_EN (1 << 17) -#define BLC_EN (1 << 18) -#define DG_EN (1 << 19) -#define SO_EN (1 << 20) -#define CTC_EN (1 << 21) -#define CONTRAST_EN (1 << 22) -#define CNR_EN (1 << 23) -#define SATU_EN (1 << 24) -#define SRC0_EN (1 << 31) -#define ISP_MODULE_EN_ALL (0xffffffff) - -/* - * ISP interrupt enable - */ -#define FINISH_INT_EN (1 << 0) -#define START_INT_EN (1 << 1) -#define PARA_SAVE_INT_EN (1 << 2) -#define PARA_LOAD_INT_EN (1 << 3) -#define SRC0_FIFO_INT_EN (1 << 4) -#define N_LINE_START_INT_EN (1 << 7) -#define FRAME_ERROR_INT_EN (1 << 8) -#define FRAME_LOST_INT_EN (1 << 14) - -#define ISP_IRQ_EN_ALL 0xffffffff - -/* - * ISP interrupt status - */ -#define FINISH_PD (1 << 0) -#define START_PD (1 << 1) -#define PARA_SAVE_PD (1 << 2) -#define PARA_LOAD_PD (1 << 3) -#define SRC0_FIFO_OF_PD (1 << 4) -#define N_LINE_START_PD (1 << 7) -#define FRAME_ERROR_PD (1 << 8) -#define CIN_FIFO_OF_PD (1 << 9) -#define DPC_FIFO_OF_PD (1 << 10) -#define D2D_FIFO_OF_PD (1 << 11) -#define BIS_FIFO_OF_PD (1 << 12) -#define CNR_FIFO_OF_PD (1 << 13) -#define FRAME_LOST_PD (1 << 14) -#define HB_SHROT_PD (1 << 16) -#define D3D_HB_PD (1 << 24) -#define PLTM_FIFO_OF_PD (1 << 25) -#define D3D_WRITE_FIFO_OF_PD (1 << 26) -#define D3D_READ_FIFO_OF_PD (1 << 27) -#define D3D_WT2CMP_FIFO_OF_PD (1 << 28) -#define WDR_WRITE_FIFO_OF_PD (1 << 29) -#define WDR_WT2CMP_FIFO_OF_PD (1 << 30) -#define WDR_READ_FIFO_OF_PD (1 << 31) - -#define ISP_IRQ_STATUS_ALL 0xffffffff - -enum isp_channel { - ISP_CH0 = 0, - ISP_CH1 = 1, - ISP_CH2 = 2, - ISP_CH3 = 3, - ISP_MAX_CH_NUM, -}; - -struct isp_size { - unsigned int width; - unsigned int height; -}; - -struct coor { - unsigned int hor; - unsigned int ver; -}; - -struct isp_size_settings { - struct coor ob_start; - struct isp_size ob_black; - struct isp_size ob_valid; -}; - -enum ready_flag { - PARA_NOT_READY = 0, - PARA_READY = 1, -}; - -enum enable_flag { - DISABLE = 0, - ENABLE = 1, -}; - -enum isp_input_tables { - LENS_GAMMA_TABLE = 0, - DRC_TABLE = 1, -}; - -enum isp_input_seq { - ISP_BGGR = 4, - ISP_RGGB = 5, - ISP_GBRG = 6, - ISP_GRBG = 7, -}; - -enum isp_output_speed { - ISP_OUTPUT_SPEED_0 = 0, - ISP_OUTPUT_SPEED_1 = 1, - ISP_OUTPUT_SPEED_2 = 2, - ISP_OUTPUT_SPEED_3 = 3, -}; - -enum isp_debug_sel { - ISP_DBG_OBC0_INPUT = 0, - ISP_DBG_OBC0_OUTPUT, - ISP_DBG_OBC1_OUTPUT, - ISP_DBG_WDR_OUTPUT, - ISP_DBG_DPC_OUTPUT, - ISP_DBG_D2D_OUTPUT, - ISP_DBG_D3D_OUTPUT, - ISP_DBG_D3D_Y_OUTPUT, - ISP_DBG_D3D_B_OUTPUT, - ISP_DBG_LSC_OUTPUT, - ISP_DBG_PLTM_OUTPUT, - ISP_DBG_CNR_R_OUTPUT, - ISP_DBG_CNR_G_OUTPUT, - ISP_DBG_CNR_B_OUTPUT, - ISP_DBG_BGC_R_OUTPUT, - ISP_DBG_BGC_G_OUTPUT, - ISP_DBG_BGC_B_OUTPUT, -}; - -#endif diff --git a/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.c b/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.c deleted file mode 100644 index 0e7464a9..00000000 --- a/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.c +++ /dev/null @@ -1,50 +0,0 @@ - -/* - * isp_platform_drv.c for isp reg config - * - * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com - * - * Authors: Zhao Wei - * - * 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 -#include "isp_platform_drv.h" -#include "sun8iw12p1/sun8iw12p1_isp_reg_cfg.h" -struct isp_platform_drv *isp_platform_curr; - -int isp_platform_register(struct isp_platform_drv *isp_drv) -{ - int platform_id; - platform_id = isp_drv->platform_id; - isp_platform_curr = isp_drv; - return 0; -} - -int isp_platform_init(unsigned int platform_id) -{ - switch (platform_id) { - case ISP_PLATFORM_SUN8IW12P1: - sun8iw12p1_isp_platform_register(); - break; - case ISP_PLATFORM_SUN8IW17P1: - sun8iw12p1_isp_platform_register(); - break; - default: - sun8iw12p1_isp_platform_register(); - break; - } - return 0; -} - -struct isp_platform_drv *isp_get_driver(void) -{ - if (NULL == isp_platform_curr) - printk("[ISP ERR] isp platform curr have not init!\n"); - return isp_platform_curr; -} - - diff --git a/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.h b/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.h deleted file mode 100644 index 25b15ea2..00000000 --- a/drivers/media/platform/sunxi-vin/vin-isp/isp_platform_drv.h +++ /dev/null @@ -1,66 +0,0 @@ - -/* - * isp_platform_drv.h for isp reg config - * - * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com - * - * Authors: Zhao Wei - * - * 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. - */ -#ifndef _ISP_PLATFORM_DRV_H_ -#define _ISP_PLATFORM_DRV_H_ -#include -#include "bsp_isp_comm.h" - -struct isp_bsp_fun_array { - - void (*map_reg_addr) (unsigned long, unsigned long); - void (*map_load_dram_addr) (unsigned long, unsigned long); - void (*map_saved_dram_addr) (unsigned long, unsigned long); - void (*isp_enable) (unsigned long, int); - void (*isp_ch_enable) (unsigned long, int, int); - void (*isp_wdr_ch_seq) (unsigned long, int); - void (*isp_set_para_ready) (unsigned long, enum ready_flag); - unsigned int (*isp_get_para_ready) (unsigned long); - void (*isp_capture_start) (unsigned long); - void (*isp_capture_stop) (unsigned long); - void (*isp_irq_enable) (unsigned long, unsigned int); - void (*isp_irq_disable) (unsigned long, unsigned int); - unsigned int (*isp_get_irq_status) (unsigned long, unsigned int); - void (*isp_clr_irq_status) (unsigned long, unsigned int); - void (*isp_debug_output_cfg) (unsigned long, int, int); - int (*isp_int_get_enable) (unsigned long); - void (*isp_set_line_int_num) (unsigned long, unsigned int); - void (*isp_set_last_blank_cycle) (unsigned long, unsigned int); - void (*isp_set_speed_mode) (unsigned long, unsigned int); - void (*isp_set_load_addr) (unsigned long, unsigned long); - void (*isp_set_saved_addr) (unsigned long, unsigned long); - void (*isp_set_table_addr) (unsigned long, enum isp_input_tables, unsigned long); - void (*isp_set_statistics_addr) (unsigned long, unsigned long); - void (*isp_channel_enable) (unsigned long, enum isp_channel); - void (*isp_update_table) (unsigned long, unsigned short); - unsigned int (*isp_get_isp_ver)(unsigned long, unsigned int *, unsigned int *); - void (*isp_module_enable) (unsigned long, unsigned int); - void (*isp_module_disable) (unsigned long, unsigned int); - void (*isp_set_wdr_mode) (unsigned long, unsigned int); - void (*isp_set_input_fmt) (unsigned long, unsigned int); - void (*isp_set_size) (unsigned long, struct isp_size *, struct isp_size *, struct coor *); - unsigned int (*isp_load_update_flag)(unsigned long); -}; - -struct isp_platform_drv { - int platform_id; - struct isp_bsp_fun_array *fun_array; -}; - -int isp_platform_register(struct isp_platform_drv *isp_drv); - -int isp_platform_init(unsigned int platform_id); - -struct isp_platform_drv *isp_get_driver(void); - - -#endif /*_ISP_PLATFORM_DRV_H_*/ diff --git a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg.h b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg.h index 8e94bd2b..15a4f015 100644 --- a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg.h +++ b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg.h @@ -1,27 +1,22 @@ -/* - ****************************************************************************** - * - * sun8iw12p1_isp_reg.h - * - * Hawkview ISP - sun8iw12p1_isp_reg.h module - * - * Copyright (c) 2014 by Allwinnertech Co., Ltd. http: - * - * Version Author Date Description - * - * 2.0 Yang Feng 2014/06/30 Second Version - * - ****************************************************************************** - */ + /* + * sun8iw12p1_isp_reg.h + * + * Copyright (c) 2007-2017 Allwinnertech Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ -#ifndef __REG20__ISP__H__ -#define __REG20__ISP__H__ - -#ifdef __cplusplus -extern "C" { - -#endif +#ifndef __ISP500__H__ +#define __ISP500__H__ /*FOR SUN8IW12P1 ISP*/ @@ -311,8 +306,4 @@ typedef union { } bits; } SUN8IW12P1_ISP_OB_VALID_START_REG_t; -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.c b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.c index cf8a5597..07049e86 100644 --- a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.c +++ b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.c @@ -1,29 +1,24 @@ /* - ****************************************************************************** - * - * sun8iw12p1_isp_reg_cfg.c - * - * Hawkview ISP - sun8iw12p1_isp_reg_cfg.c module - * - * Copyright (c) 2014 by Allwinnertech Co., Ltd. http: - * - * Version Author Date Description - * - * 2.0 Yang Feng 2014/06/30 Second Version - * - ****************************************************************************** - */ + * sun8iw12p1_isp_reg_cfg.c + * + * Copyright (c) 2007-2017 Allwinnertech Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ #include -#include "../isp_platform_drv.h" #include "sun8iw12p1_isp_reg.h" #include "sun8iw12p1_isp_reg_cfg.h" -#include - -/*#define USE_DEF_PARA*/ - #define SUN8IW12P1_ISP_MAX_NUM 2 /* @@ -62,7 +57,7 @@ struct sun8iw12p1_isp_reg sun8iw12p1_isp_regs[SUN8IW12P1_ISP_MAX_NUM]; * Register Address */ -void sun8iw12p1_map_reg_addr(unsigned long id, unsigned long isp_reg_base) +void bsp_isp_map_reg_addr(unsigned long id, unsigned long isp_reg_base) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_cfg = (SUN8IW12P1_ISP_FE_CFG_REG_t *) (isp_reg_base + SUN8IW12P1_ISP_FE_CFG_REG_OFF); sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl = (SUN8IW12P1_ISP_FE_CTRL_REG_t *) (isp_reg_base + SUN8IW12P1_ISP_FE_CTRL_REG_OFF); @@ -95,7 +90,7 @@ void sun8iw12p1_map_reg_addr(unsigned long id, unsigned long isp_reg_base) * Load DRAM Register Address */ -void sun8iw12p1_map_load_dram_addr(unsigned long id, unsigned long isp_load_dram_base) +void bsp_isp_map_load_dram_addr(unsigned long id, unsigned long isp_load_dram_base) { #ifndef USE_DEF_PARA sun8iw12p1_isp_regs[id].sun8iw12p1_isp_update_flag = (SUN8IW12P1_ISP_FE_CTRL_REG_t *) (isp_load_dram_base + SUN8IW12P1_ISP_FE_CTRL_REG_OFF); @@ -110,17 +105,17 @@ void sun8iw12p1_map_load_dram_addr(unsigned long id, unsigned long isp_load_dram /* * Saved DRAM Register Address */ -void sun8iw12p1_map_saved_dram_addr(unsigned long id, unsigned long isp_saved_dram_base) +void bsp_isp_map_saved_dram_addr(unsigned long id, unsigned long base) { } -void sun8iw12p1_isp_enable(unsigned long id, int enable) +void bsp_isp_enable(unsigned long id, int enable) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_cfg->bits.isp_enable = enable; } -void sun8iw12p1_isp_ch_enable(unsigned long id, int ch, int enable) +void bsp_isp_ch_enable(unsigned long id, int ch, int enable) { switch (ch) { case 0: @@ -141,7 +136,7 @@ void sun8iw12p1_isp_ch_enable(unsigned long id, int ch, int enable) } } -void sun8iw12p1_isp_wdr_ch_seq(unsigned long id, int seq) +void bsp_isp_wdr_ch_seq(unsigned long id, int seq) { switch (seq) { case 0: @@ -155,7 +150,7 @@ void sun8iw12p1_isp_wdr_ch_seq(unsigned long id, int seq) break; } } -void sun8iw12p1_isp_set_para_ready(unsigned long id, enum ready_flag ready) +void bsp_isp_set_para_ready(unsigned long id, enum ready_flag ready) { #ifndef USE_DEF_PARA if (ready == PARA_READY) @@ -165,12 +160,12 @@ void sun8iw12p1_isp_set_para_ready(unsigned long id, enum ready_flag ready) #endif } -unsigned int sun8iw12p1_isp_get_para_ready(unsigned long id) +unsigned int bsp_isp_get_para_ready(unsigned long id) { return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl->bits.para_ready; } -void sun8iw12p1_isp_update_table(unsigned long id, unsigned short table_update) +void bsp_isp_update_table(unsigned long id, unsigned short table_update) { if (table_update & LINEAR_UPDATE) sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl->bits.linear_update = 1; @@ -227,72 +222,72 @@ void sun8iw12p1_isp_update_table(unsigned long id, unsigned short table_update) else sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl->bits.contrast_update = 0; } -void sun8iw12p1_isp_capture_start(unsigned long id) +void bsp_isp_capture_start(unsigned long id) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl->bits.cap_en = 1; } -void sun8iw12p1_isp_capture_stop(unsigned long id) +void bsp_isp_capture_stop(unsigned long id) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_ctrl->bits.cap_en = 0; } -void sun8iw12p1_isp_irq_enable(unsigned long id, unsigned int irq_flag) +void bsp_isp_irq_enable(unsigned long id, unsigned int irq_flag) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_int_en->dwval |= irq_flag; } -void sun8iw12p1_isp_irq_disable(unsigned long id, unsigned int irq_flag) +void bsp_isp_irq_disable(unsigned long id, unsigned int irq_flag) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_int_en->dwval &= ~irq_flag; } -int sun8iw12p1_isp_int_get_enable(unsigned long id) +int bsp_isp_int_get_enable(unsigned long id) { return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_int_en->dwval; } -unsigned int sun8iw12p1_isp_get_irq_status(unsigned long id, unsigned int irq_flag) +unsigned int bsp_isp_get_irq_status(unsigned long id, unsigned int irq_flag) { return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_int_sta->dwval & irq_flag; } -void sun8iw12p1_isp_clr_irq_status(unsigned long id, unsigned int irq_flag) +void bsp_isp_clr_irq_status(unsigned long id, unsigned int irq_flag) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_fe_int_sta->dwval = irq_flag; } -void sun8iw12p1_isp_debug_output_cfg(unsigned long id, int enable, int output_sel) +void bsp_isp_debug_output_cfg(unsigned long id, int enable, int output_sel) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_dbg_output->bits.debug_en = enable; sun8iw12p1_isp_regs[id].sun8iw12p1_isp_dbg_output->bits.debug_sel = output_sel; } -void sun8iw12p1_isp_set_line_int_num(unsigned long id, unsigned int line_num) +void bsp_isp_set_line_int_num(unsigned long id, unsigned int line_num) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_line_int_num->bits.line_int_num = line_num; } -void sun8iw12p1_isp_set_last_blank_cycle(unsigned long id, unsigned int last_blank_cycle) +void bsp_isp_set_last_blank_cycle(unsigned long id, unsigned int last_blank_cycle) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_line_int_num->bits.last_blank_cycle = last_blank_cycle; } -void sun8iw12p1_isp_set_speed_mode(unsigned long id, unsigned int speed_mode) +void bsp_isp_set_speed_mode(unsigned long id, unsigned int speed_mode) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_rot_of_cfg->bits.speed_mode = speed_mode; } -void sun8iw12p1_isp_set_load_addr(unsigned long id, unsigned long addr) +void bsp_isp_set_load_addr(unsigned long id, unsigned long addr) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_reg_load_addr->dwval = addr >> ISP_ADDR_BIT_R_SHIFT; } -void sun8iw12p1_isp_set_saved_addr(unsigned long id, unsigned long addr) +void bsp_isp_set_saved_addr(unsigned long id, unsigned long addr) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_reg_saved_addr->dwval = addr >> ISP_ADDR_BIT_R_SHIFT; } -void sun8iw12p1_isp_set_table_addr(unsigned long id, enum isp_input_tables table, +void bsp_isp_set_table_addr(unsigned long id, enum isp_input_tables table, unsigned long addr) { switch (table) { @@ -307,29 +302,29 @@ void sun8iw12p1_isp_set_table_addr(unsigned long id, enum isp_input_tables table } } -void sun8iw12p1_isp_set_statistics_addr(unsigned long id, unsigned long addr) +void bsp_isp_set_statistics_addr(unsigned long id, unsigned long addr) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_statistics_addr->dwval = addr >> ISP_ADDR_BIT_R_SHIFT; } -unsigned int sun8iw12p1_isp_get_isp_ver(unsigned long id, unsigned int *major, unsigned int *minor) +unsigned int bsp_isp_get_isp_ver(unsigned long id, unsigned int *major, unsigned int *minor) { *major = sun8iw12p1_isp_regs[id].sun8iw12p1_isp_ver_cfg->bits.major_ver; *minor = sun8iw12p1_isp_regs[id].sun8iw12p1_isp_ver_cfg->bits.minor_ver; return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_ver_cfg->dwval; } -void sun8iw12p1_isp_module_enable(unsigned long id, unsigned int modules) +void bsp_isp_module_enable(unsigned long id, unsigned int modules) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_en->dwval |= modules; } -void sun8iw12p1_isp_module_disable(unsigned long id, unsigned int modules) +void bsp_isp_module_disable(unsigned long id, unsigned int modules) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_en->dwval &= ~modules; } -void sun8iw12p1_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode) +void bsp_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode) { if (wdr_mode == 1) {/*dol*/ sun8iw12p1_isp_regs[id].sun8iw12p1_isp_mode->bits.wdr_mode = 0; @@ -343,12 +338,12 @@ void sun8iw12p1_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode) } } -void sun8iw12p1_isp_set_input_fmt(unsigned long id, unsigned int fmt) +void bsp_isp_set_input_fmt(unsigned long id, unsigned int fmt) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_mode->bits.input_fmt = fmt; } -void sun8iw12p1_isp_set_size(unsigned long id, struct isp_size *black, +void bsp_isp_set_ob(unsigned long id, struct isp_size *black, struct isp_size *valid, struct coor *xy) { sun8iw12p1_isp_regs[id].sun8iw12p1_isp_ob_size->bits.ob_width = black->width; @@ -359,53 +354,13 @@ void sun8iw12p1_isp_set_size(unsigned long id, struct isp_size *black, sun8iw12p1_isp_regs[id].sun8iw12p1_isp_ob_valid_start->bits.ob_ver_start = xy->ver; } -unsigned int sun8iw12p1_isp_load_update_flag(unsigned long id) +void bsp_isp_set_size(unsigned long id, struct isp_size_settings *size) { - return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_update_flag->dwval; + bsp_isp_set_ob(id, &size->ob_black, &size->ob_valid, &size->ob_start); } -static struct isp_bsp_fun_array sun8iw12p1_fun_array = { - .map_reg_addr = sun8iw12p1_map_reg_addr, - .map_load_dram_addr = sun8iw12p1_map_load_dram_addr, - .map_saved_dram_addr = sun8iw12p1_map_saved_dram_addr, - .isp_enable = sun8iw12p1_isp_enable, - .isp_ch_enable = sun8iw12p1_isp_ch_enable, - .isp_wdr_ch_seq = sun8iw12p1_isp_wdr_ch_seq, - .isp_set_para_ready = sun8iw12p1_isp_set_para_ready, - .isp_get_para_ready = sun8iw12p1_isp_get_para_ready, - .isp_capture_start = sun8iw12p1_isp_capture_start, - .isp_capture_stop = sun8iw12p1_isp_capture_stop, - .isp_irq_enable = sun8iw12p1_isp_irq_enable, - .isp_irq_disable = sun8iw12p1_isp_irq_disable, - .isp_get_irq_status = sun8iw12p1_isp_get_irq_status, - .isp_clr_irq_status = sun8iw12p1_isp_clr_irq_status, - .isp_debug_output_cfg = sun8iw12p1_isp_debug_output_cfg, - .isp_int_get_enable = sun8iw12p1_isp_int_get_enable, - .isp_set_line_int_num = sun8iw12p1_isp_set_line_int_num, - .isp_set_last_blank_cycle = sun8iw12p1_isp_set_last_blank_cycle, - .isp_set_speed_mode = sun8iw12p1_isp_set_speed_mode, - .isp_set_load_addr = sun8iw12p1_isp_set_load_addr, - .isp_set_saved_addr = sun8iw12p1_isp_set_saved_addr, - .isp_set_table_addr = sun8iw12p1_isp_set_table_addr, - .isp_set_statistics_addr = sun8iw12p1_isp_set_statistics_addr, - .isp_update_table = sun8iw12p1_isp_update_table, - .isp_get_isp_ver = sun8iw12p1_isp_get_isp_ver, - .isp_module_enable = sun8iw12p1_isp_module_enable, - .isp_module_disable = sun8iw12p1_isp_module_disable, - .isp_set_wdr_mode = sun8iw12p1_isp_set_wdr_mode, - .isp_set_input_fmt = sun8iw12p1_isp_set_input_fmt, - .isp_set_size = sun8iw12p1_isp_set_size, - .isp_load_update_flag = sun8iw12p1_isp_load_update_flag, -}; - -struct isp_platform_drv sun8iw12p1_isp_drv = { - .platform_id = ISP_PLATFORM_SUN8IW12P1, - .fun_array = &sun8iw12p1_fun_array, -}; - -int sun8iw12p1_isp_platform_register(void) +unsigned int bsp_isp_load_update_flag(unsigned long id) { - return isp_platform_register(&sun8iw12p1_isp_drv); + return sun8iw12p1_isp_regs[id].sun8iw12p1_isp_update_flag->dwval; } - diff --git a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.h b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.h index ec3d5ce5..19bbc6bc 100644 --- a/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.h +++ b/drivers/media/platform/sunxi-vin/vin-isp/sun8iw12p1/sun8iw12p1_isp_reg_cfg.h @@ -1,23 +1,279 @@ /* - ****************************************************************************** - * - * sun8iw12p1_isp_reg_cfg.h - * - * Hawkview ISP - sun8iw12p1_isp_reg_cfg.h module - * - * Copyright (c) 2014 by Allwinnertech Co., Ltd. http: - * - * Version Author Date Description - * - * 2.0 Yang Feng 2014/06/30 Second Version - * - ****************************************************************************** - */ + * sun8iw12p1_isp_reg_cfg.h + * + * Copyright (c) 2007-2017 Allwinnertech Co., Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + #ifndef _SUN8IW12P1_ISP_REG_CFG_H_ #define _SUN8IW12P1_ISP_REG_CFG_H_ #define ISP_ADDR_BIT_R_SHIFT 2 -int sun8iw12p1_isp_platform_register(void); + +/*ISP size configs*/ +#define ISP_REG_SIZE 0x400 +#define ISP_LOAD_REG_SIZE 0x400 +#define ISP_SAVED_REG_SIZE 0x400 + +/*stat size configs*/ + +#define ISP_STAT_TOTAL_SIZE 0xAB00 + +#define ISP_STAT_HIST_MEM_SIZE 0x0200 +#define ISP_STAT_AE_MEM_SIZE 0x4800 +#define ISP_STAT_AF_MEM_SIZE 0x0500 +#define ISP_STAT_AFS_MEM_SIZE 0x0200 +#define ISP_STAT_AWB_RGB_MEM_SIZE 0x4800 +#define ISP_STAT_AWB_CNT_MEM_SIZE 0x0C00 +#define ISP_STAT_PLTM_LST_MEM_SIZE 0x0600 + +#define ISP_STAT_HIST_MEM_OFS 0x0000 +#define ISP_STAT_AE_MEM_OFS 0x0200 +#define ISP_STAT_AF_MEM_OFS 0x4a00 +#define ISP_STAT_AFS_MEM_OFS 0x4f00 +#define ISP_STAT_AWB_MEM_OFS 0x5100 +#define ISP_STAT_PLTM_LST_MEM_OFS 0xa500 + +/*table size configs*/ + +#define ISP_TABLE_MAPPING1_SIZE 0x5a00 +#define ISP_LSC_MEM_SIZE (256*8) +#define ISP_GAMMA_MEM_SIZE (256*4) +#define ISP_LINEAR_MEM_SIZE (256*6) +#define ISP_WDR_GAMMA_FE_MEM_SIZE (4096*2) +#define ISP_WDR_GAMMA_BE_MEM_SIZE (4096*2) +#define ISP_TDNF_DIFF_MEM_SIZE (256*1) +#define ISP_PLTM_H_MEM_SIZE (256*1) +#define ISP_PLTM_V_MEM_SIZE (256*1) +#define ISP_PLTM_POW_MEM_SIZE (256*2) +#define ISP_PLTM_F_MEM_SIZE (256*2) +#define ISP_CONTRAST_PE_MEM_SIZE (128*2) + +#define ISP_TABLE_MAPPING2_SIZE 0x1f00 +#define ISP_DRC_MEM_SIZE (256*2) +#define ISP_SATURATION_MEM_SIZE (256*2) +#define ISP_CEM_MEM_SIZE (736*8) + +#define ISP_LSC_MEM_OFS 0x0 +#define ISP_GAMMA_MEM_OFS 0x0800 +#define ISP_LINEAR_MEM_OFS 0x0c00 +#define ISP_WDR_GAMMA_FE_MEM_OFS 0x1200 +#define ISP_WDR_GAMMA_BE_MEM_OFS 0x3200 +#define ISP_TDNF_DIFF_MEM_OFS 0x5200 +#define ISP_PLTM_H_MEM_OFS 0x5300 +#define ISP_PLTM_V_MEM_OFS 0x5400 +#define ISP_PLTM_POW_MEM_OFS 0x5500 +#define ISP_PLTM_F_MEM_OFS 0x5700 +#define ISP_CONTRAST_PE_MEM_OFS 0x5900 + +#define ISP_DRC_MEM_OFS 0x0 +#define ISP_SATURATION_MEM_OFS 0x0600 +#define ISP_CEM_MEM_OFS 0x0800 + +/* + * update table + */ +#define LUT_UPDATE (1 << 3) +#define LINEAR_UPDATE (1 << 3) +#define LENS_UPDATE (1 << 4) +#define GAMMA_UPDATE (1 << 5) +#define DRC_UPDATE (1 << 6) +#define DISC_UPDATE (1 << 7) +#define SATU_UPDATE (1 << 8) +#define WDR_UPDATE (1 << 9) +#define TDNF_UPDATE (1 << 10) +#define PLTM_UPDATE (1 << 11) +#define CEM_UPDATE (1 << 12) +#define CONTRAST_UPDATE (1 << 13) + +#define TABLE_UPDATE_ALL 0xffffffff + +/* + * ISP Module enable + */ +#define AE_EN (1 << 0) +#define LC_EN (1 << 1) +#define WDR_EN (1 << 2) +#define OTF_DPC_EN (1 << 3) +#define BDNF_EN (1 << 4) +#define TDNF_EN (1 << 5) +#define AWB_EN (1 << 6) +#define WB_EN (1 << 7) +#define LSC_EN (1 << 8) +#define BGC_EN (1 << 9) +#define SAP_EN (1 << 10) +#define AF_EN (1 << 11) +#define RGB2RGB_EN (1 << 12) +#define RGB_DRC_EN (1 << 13) +#define PLTM_EN (1 << 14) +#define CEM_EN (1 << 15) +#define AFS_EN (1 << 16) +#define HIST_EN (1 << 17) +#define BLC_EN (1 << 18) +#define DG_EN (1 << 19) +#define SO_EN (1 << 20) +#define CTC_EN (1 << 21) +#define CONTRAST_EN (1 << 22) +#define CNR_EN (1 << 23) +#define SATU_EN (1 << 24) +#define SRC0_EN (1 << 31) +#define ISP_MODULE_EN_ALL (0xffffffff) + +/* + * ISP interrupt enable + */ +#define FINISH_INT_EN (1 << 0) +#define START_INT_EN (1 << 1) +#define PARA_SAVE_INT_EN (1 << 2) +#define PARA_LOAD_INT_EN (1 << 3) +#define SRC0_FIFO_INT_EN (1 << 4) +#define N_LINE_START_INT_EN (1 << 7) +#define FRAME_ERROR_INT_EN (1 << 8) +#define FRAME_LOST_INT_EN (1 << 14) + +#define ISP_IRQ_EN_ALL 0xffffffff + +/* + * ISP interrupt status + */ +#define FINISH_PD (1 << 0) +#define START_PD (1 << 1) +#define PARA_SAVE_PD (1 << 2) +#define PARA_LOAD_PD (1 << 3) +#define SRC0_FIFO_OF_PD (1 << 4) +#define N_LINE_START_PD (1 << 7) +#define FRAME_ERROR_PD (1 << 8) +#define CIN_FIFO_OF_PD (1 << 9) +#define DPC_FIFO_OF_PD (1 << 10) +#define D2D_FIFO_OF_PD (1 << 11) +#define BIS_FIFO_OF_PD (1 << 12) +#define CNR_FIFO_OF_PD (1 << 13) +#define FRAME_LOST_PD (1 << 14) +#define HB_SHROT_PD (1 << 16) +#define D3D_HB_PD (1 << 24) +#define PLTM_FIFO_OF_PD (1 << 25) +#define D3D_WRITE_FIFO_OF_PD (1 << 26) +#define D3D_READ_FIFO_OF_PD (1 << 27) +#define D3D_WT2CMP_FIFO_OF_PD (1 << 28) +#define WDR_WRITE_FIFO_OF_PD (1 << 29) +#define WDR_WT2CMP_FIFO_OF_PD (1 << 30) +#define WDR_READ_FIFO_OF_PD (1 << 31) + +#define ISP_IRQ_STATUS_ALL 0xffffffff + +enum isp_channel { + ISP_CH0 = 0, + ISP_CH1 = 1, + ISP_CH2 = 2, + ISP_CH3 = 3, + ISP_MAX_CH_NUM, +}; + +struct isp_size { + unsigned int width; + unsigned int height; +}; + +struct coor { + unsigned int hor; + unsigned int ver; +}; + +struct isp_size_settings { + struct coor ob_start; + struct isp_size ob_black; + struct isp_size ob_valid; +}; + +enum ready_flag { + PARA_NOT_READY = 0, + PARA_READY = 1, +}; + +enum enable_flag { + DISABLE = 0, + ENABLE = 1, +}; + +enum isp_input_tables { + LENS_GAMMA_TABLE = 0, + DRC_TABLE = 1, +}; + +enum isp_input_seq { + ISP_BGGR = 4, + ISP_RGGB = 5, + ISP_GBRG = 6, + ISP_GRBG = 7, +}; + +enum isp_output_speed { + ISP_OUTPUT_SPEED_0 = 0, + ISP_OUTPUT_SPEED_1 = 1, + ISP_OUTPUT_SPEED_2 = 2, + ISP_OUTPUT_SPEED_3 = 3, +}; + +enum isp_debug_sel { + ISP_DBG_OBC0_INPUT = 0, + ISP_DBG_OBC0_OUTPUT, + ISP_DBG_OBC1_OUTPUT, + ISP_DBG_WDR_OUTPUT, + ISP_DBG_DPC_OUTPUT, + ISP_DBG_D2D_OUTPUT, + ISP_DBG_D3D_OUTPUT, + ISP_DBG_D3D_Y_OUTPUT, + ISP_DBG_D3D_B_OUTPUT, + ISP_DBG_LSC_OUTPUT, + ISP_DBG_PLTM_OUTPUT, + ISP_DBG_CNR_R_OUTPUT, + ISP_DBG_CNR_G_OUTPUT, + ISP_DBG_CNR_B_OUTPUT, + ISP_DBG_BGC_R_OUTPUT, + ISP_DBG_BGC_G_OUTPUT, + ISP_DBG_BGC_B_OUTPUT, +}; + +void bsp_isp_map_reg_addr(unsigned long id, unsigned long base); +void bsp_isp_map_load_dram_addr(unsigned long id, unsigned long base); +void bsp_isp_map_saved_dram_addr(unsigned long id, unsigned long base); +void bsp_isp_enable(unsigned long id, int enable); +void bsp_isp_ch_enable(unsigned long id, int ch, int enable); +void bsp_isp_wdr_ch_seq(unsigned long id, int seq); +void bsp_isp_set_para_ready(unsigned long id, enum ready_flag ready); +unsigned int bsp_isp_get_para_ready(unsigned long id); +void bsp_isp_update_table(unsigned long id, unsigned short table_update); +void bsp_isp_capture_start(unsigned long id); +void bsp_isp_capture_stop(unsigned long id); +void bsp_isp_irq_enable(unsigned long id, unsigned int irq_flag); +void bsp_isp_irq_disable(unsigned long id, unsigned int irq_flag); +int bsp_isp_int_get_enable(unsigned long id); +unsigned int bsp_isp_get_irq_status(unsigned long id, unsigned int irq_flag); +void bsp_isp_clr_irq_status(unsigned long id, unsigned int irq_flag); +void bsp_isp_debug_output_cfg(unsigned long id, int enable, int output_sel); +void bsp_isp_set_line_int_num(unsigned long id, unsigned int line_num); +void bsp_isp_set_last_blank_cycle(unsigned long id, unsigned int last_blank_cycle); +void bsp_isp_set_speed_mode(unsigned long id, unsigned int speed_mode); +void bsp_isp_set_load_addr(unsigned long id, unsigned long addr); +void bsp_isp_set_saved_addr(unsigned long id, unsigned long addr); +void bsp_isp_set_table_addr(unsigned long id, enum isp_input_tables table, unsigned long addr); +void bsp_isp_set_statistics_addr(unsigned long id, unsigned long addr); +unsigned int bsp_isp_get_isp_ver(unsigned long id, unsigned int *major, unsigned int *minor); +void bsp_isp_module_enable(unsigned long id, unsigned int modules); +void bsp_isp_module_disable(unsigned long id, unsigned int modules); +void bsp_isp_set_wdr_mode(unsigned long id, unsigned int wdr_mode); +void bsp_isp_set_input_fmt(unsigned long id, unsigned int fmt); +void bsp_isp_set_size(unsigned long id, struct isp_size_settings *size); +unsigned int bsp_isp_load_update_flag(unsigned long id); #endif /*_SUN8IW12P1_ISP_REG_CFG_H_*/ diff --git a/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.c b/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.c index eb3c0e63..a1c753a3 100644 --- a/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.c +++ b/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.c @@ -149,19 +149,16 @@ static int isp_3d_pingpong_alloc(struct isp_dev *isp) { int ret = 0; - isp->isp_3d_buf.flags[0] = ISP_3D_R; - isp->isp_3d_buf.flags[1] = ISP_3D_W; + isp->d3d_pingpong[0].size = isp->mf.width * isp->mf.height * 4; + isp->d3d_pingpong[1].size = isp->mf.width * isp->mf.height * 4; - isp->isp_3d_buf.buf[0].size = isp->mf.width * isp->mf.height * 4; - isp->isp_3d_buf.buf[1].size = isp->mf.width * isp->mf.height * 4; - - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_3d_buf.buf[0]); + ret = os_mem_alloc(&isp->pdev->dev, &isp->d3d_pingpong[0]); if (ret < 0) { vin_err("isp 3d pingpong buf0 requset add failed!\n"); return -ENOMEM; } - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_3d_buf.buf[1]); + ret = os_mem_alloc(&isp->pdev->dev, &isp->d3d_pingpong[1]); if (ret < 0) { vin_err("isp 3d pingpong buf1 requset add failed!\n"); return -ENOMEM; @@ -171,23 +168,22 @@ static int isp_3d_pingpong_alloc(struct isp_dev *isp) } static void isp_3d_pingpong_free(struct isp_dev *isp) { - os_mem_free(&isp->pdev->dev, &isp->isp_3d_buf.buf[0]); - os_mem_free(&isp->pdev->dev, &isp->isp_3d_buf.buf[1]); + os_mem_free(&isp->pdev->dev, &isp->d3d_pingpong[0]); + os_mem_free(&isp->pdev->dev, &isp->d3d_pingpong[1]); } -static int isp_3d_pingpong_update(struct isp_dev *isp, - struct isp_hw_pingpong *pingpong) +static int isp_3d_pingpong_update(struct isp_dev *isp) { dma_addr_t addr; - int tmp = -1; + struct vin_mm tmp; - tmp = pingpong->flags[0]; - pingpong->flags[0] = pingpong->flags[1]; - pingpong->flags[1] = tmp; + tmp = isp->d3d_pingpong[0]; + isp->d3d_pingpong[0] = isp->d3d_pingpong[1]; + isp->d3d_pingpong[1] = tmp; - addr = (dma_addr_t)pingpong->buf[pingpong->flags[ISP_3D_W]].dma_addr; + addr = (dma_addr_t)isp->d3d_pingpong[0].dma_addr; writel(addr >> 2, isp->isp_load.vir_addr + 0xc8); - addr = (dma_addr_t)pingpong->buf[pingpong->flags[ISP_3D_R]].dma_addr; + addr = (dma_addr_t)isp->d3d_pingpong[1].dma_addr; writel(addr >> 2, isp->isp_load.vir_addr + 0xcc); return 0; @@ -300,6 +296,7 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) if (enable) { isp->h3a_stat.frame_number = 0; + isp->ptn_isp_cnt = 0; if (isp->load_flag) memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_REG_SIZE); #if ISP_STAT_EN @@ -310,7 +307,7 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) if (isp->large_image == 0) { if (isp_3d_pingpong_alloc(isp)) return -ENOMEM; - isp_3d_pingpong_update(isp, &isp->isp_3d_buf); + isp_3d_pingpong_update(isp); } if (isp->wdr_mode != ISP_NORMAL_MODE) { if (isp_wdr_pingpong_alloc(isp)) { @@ -320,7 +317,7 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) isp_wdr_pingpong_set(isp); memcpy(wdr_tbl, wdr_dol_tbl, ISP_WDR_GAMMA_FE_MEM_SIZE + ISP_WDR_GAMMA_BE_MEM_SIZE); } - bsp_isp_enable(isp->id); + bsp_isp_enable(isp->id, 1); bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL); bsp_isp_irq_enable(isp->id, FINISH_INT_EN | PARA_LOAD_INT_EN | SRC0_FIFO_INT_EN | FRAME_ERROR_INT_EN | FRAME_LOST_INT_EN); @@ -330,7 +327,7 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) load_val = load_val | WDR_UPDATE; bsp_isp_module_enable(isp->id, WDR_EN); bsp_isp_set_wdr_mode(isp->id, ISP_DOL_WDR_MODE); - bsp_isp_channel_enable(isp->id, 1); + bsp_isp_ch_enable(isp->id, ISP_CH1, 1); } else if (isp->wdr_mode == ISP_COMANDING_MODE) { load_val = load_val | WDR_UPDATE; bsp_isp_module_enable(isp->id, WDR_EN); @@ -346,12 +343,12 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) bsp_isp_module_enable(isp->id, SRC0_EN); bsp_isp_set_input_fmt(isp->id, isp->isp_fmt->infmt); - bsp_isp_set_ob_zone(isp->id, &isp->isp_ob); + bsp_isp_set_size(isp->id, &isp->isp_ob); /*sunxi_isp_dump_regs(sd);*/ - bsp_isp_set_para_ready(isp->id); - bsp_isp_set_last_blank_cycle(isp->id, 7); - bsp_isp_set_speed_mode(isp->id, 6); - bsp_isp_channel_enable(isp->id, 0); + bsp_isp_set_para_ready(isp->id, PARA_READY); + bsp_isp_set_last_blank_cycle(isp->id, 5); + bsp_isp_set_speed_mode(isp->id, 3); + bsp_isp_ch_enable(isp->id, ISP_CH0, 1); bsp_isp_capture_start(isp->id); } else { #if ISP_STAT_EN @@ -363,14 +360,14 @@ static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable) v4l2_event_queue(isp->subdev.devnode, &event); bsp_isp_capture_stop(isp->id); bsp_isp_module_disable(isp->id, SRC0_EN); - bsp_isp_channel_disable(isp->id, 0); + bsp_isp_ch_enable(isp->id, ISP_CH0, 0); bsp_isp_irq_disable(isp->id, ISP_IRQ_EN_ALL); bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL); - bsp_isp_disable(isp->id); + bsp_isp_enable(isp->id, 0); if (isp->large_image == 0) isp_3d_pingpong_free(isp); if (isp->wdr_mode != ISP_NORMAL_MODE) { - bsp_isp_channel_disable(isp->id, 1); + bsp_isp_ch_enable(isp->id, ISP_CH1, 0); isp_wdr_pingpong_free(isp); } isp->f1_after_librun = 0; @@ -591,15 +588,18 @@ int sunxi_isp_subdev_init(struct v4l2_subdev *sd, u32 val) isp->load_flag = 0; isp->have_init = 1; } + isp->h3a_stat.buf[0].empty = 1; + isp->h3a_stat.buf[0].dma_addr = isp->isp_stat.dma_addr; + isp->h3a_stat.buf[0].virt_addr = isp->isp_stat.vir_addr; bsp_isp_set_statistics_addr(isp->id, (dma_addr_t)isp->isp_stat.dma_addr); - bsp_isp_set_dma_load_addr(isp->id, (unsigned long)isp->isp_load.dma_addr); - bsp_isp_set_dma_saved_addr(isp->id, (unsigned long)isp->isp_save.dma_addr); - bsp_isp_update_lens_gamma_table(isp->id, &isp->isp_tbl); - bsp_isp_update_drc_table(isp->id, &isp->isp_tbl); + bsp_isp_set_load_addr(isp->id, (unsigned long)isp->isp_load.dma_addr); + bsp_isp_set_saved_addr(isp->id, (unsigned long)isp->isp_save.dma_addr); + bsp_isp_set_table_addr(isp->id, LENS_GAMMA_TABLE, (unsigned long)(isp->isp_tbl.isp_lsc_tbl_dma_addr)); + bsp_isp_set_table_addr(isp->id, DRC_TABLE, (unsigned long)(isp->isp_tbl.isp_drc_tbl_dma_addr)); INIT_WORK(&isp->isp_isr_bh_task, isp_isr_bh_handle); - bsp_isp_clr_para_ready(isp->id); + bsp_isp_set_para_ready(isp->id, PARA_NOT_READY); } else { flush_work(&isp->isp_isr_bh_task); } @@ -628,7 +628,10 @@ static int __isp_set_table1_map(struct v4l2_subdev *sd, struct isp_table_reg_map vin_err("isp->isp_lut_tbl.vir_addr is NULL!\n"); return -ENOMEM; } - ret = copy_from_user(isp->isp_lut_tbl.vir_addr, tbl->addr, tbl->size); + if (isp->ptn_type) + ret = copy_from_user(&isp->load_lut_tbl[0], tbl->addr, tbl->size); + else + ret = copy_from_user(isp->isp_lut_tbl.vir_addr, tbl->addr, tbl->size); if (ret < 0) { vin_err("copy table mapping1 from usr error!\n"); return ret; @@ -649,7 +652,10 @@ static int __isp_set_table2_map(struct v4l2_subdev *sd, struct isp_table_reg_map vin_err("isp->isp_drc_tbl.vir_addr is NULL!\n"); return -ENOMEM; } - ret = copy_from_user(isp->isp_drc_tbl.vir_addr, tbl->addr, tbl->size); + if (isp->ptn_type) + ret = copy_from_user(&isp->load_drc_tbl[0], tbl->addr, tbl->size); + else + ret = copy_from_user(isp->isp_drc_tbl.vir_addr, tbl->addr, tbl->size); if (ret < 0) { vin_err("copy table mapping2 from usr error!\n"); return ret; @@ -807,7 +813,7 @@ static void __sunxi_isp_reset(struct isp_dev *isp) vipp_top_clk_en(vinc->vipp_sel, 0); } } - bsp_isp_disable(isp->id); + bsp_isp_enable(isp->id, 0); bsp_isp_capture_stop(isp->id); /*****************start*******************/ @@ -827,7 +833,7 @@ static void __sunxi_isp_reset(struct isp_dev *isp) } } - bsp_isp_enable(isp->id); + bsp_isp_enable(isp->id, 1); bsp_isp_capture_start(isp->id); csic_prs_enable(vinc->csi_sel); @@ -994,8 +1000,8 @@ static int sunxi_isp_s_ctrl(struct v4l2_ctrl *ctrl) unsigned long flags; int ret; - vin_log(VIN_LOG_ISP, "id = %d, val = %d, cur.val = %d\n", - ctrl->id, ctrl->val, ctrl->cur.val); + vin_log(VIN_LOG_ISP, "%s, val = %d, cur.val = %d\n", + v4l2_ctrl_get_name(ctrl->id), ctrl->val, ctrl->cur.val); spin_lock_irqsave(&isp->slock, flags); ret = __sunxi_isp_ctrl(isp, ctrl); spin_unlock_irqrestore(&isp->slock, flags); @@ -1003,8 +1009,44 @@ static int sunxi_isp_s_ctrl(struct v4l2_ctrl *ctrl) return ret; } +static int sunxi_isp_try_ctrl(struct v4l2_ctrl *ctrl) +{ + /* + * to cheat control framework, because of when ctrl->cur.val == ctrl->val + * s_ctrl would not be called + */ + if ((ctrl->minimum == 0) && (ctrl->maximum == 1)) { + if (ctrl->val) + ctrl->cur.val = 0; + else + ctrl->cur.val = 1; + } else { + if (ctrl->val == ctrl->maximum) + ctrl->cur.val = ctrl->val - 1; + else + ctrl->cur.val = ctrl->val + 1; + } + + /* + * to cheat control framework, because of when ctrl->flags is + * V4L2_CTRL_FLAG_VOLATILE, s_ctrl would not be called + */ + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + case V4L2_CID_EXPOSURE_ABSOLUTE: + case V4L2_CID_GAIN: + if (ctrl->val != ctrl->cur.val) + ctrl->flags &= ~V4L2_CTRL_FLAG_VOLATILE; + break; + default: + break; + } + return 0; +} + static const struct v4l2_ctrl_ops sunxi_isp_ctrl_ops = { .s_ctrl = sunxi_isp_s_ctrl, + .try_ctrl = sunxi_isp_try_ctrl, }; static const struct v4l2_ctrl_config ae_win_ctrls[] = { @@ -1235,13 +1277,9 @@ int __isp_init_subdev(struct isp_dev *isp) v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_SATURATION, -256, 512, 1, 0); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); - ctrl = v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE, 0, 65536 * 16, 1, 0); - if (ctrl != NULL) - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; - + v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE, 1, 65536 * 16, 1, 1); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_GAIN, - 1 * 1600, 256 * 1600, 1, 1 * 1600); + v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_GAIN, 16, 6000 * 16, 1, 16); v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_POWER_LINE_FREQUENCY, @@ -1261,7 +1299,7 @@ int __isp_init_subdev(struct isp_dev *isp) v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_APERTURE_PRIORITY, 0, V4L2_EXPOSURE_AUTO); - v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, 1000000, 1, 1); + v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, 30 * 1000000, 1, 1); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_AUTO_PRIORITY, 0, 1, 1, 0); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 127, 1, 0); v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FOCUS_RELATIVE, -127, 127, 1, 0); @@ -1330,84 +1368,45 @@ int __isp_init_subdev(struct isp_dev *isp) static int isp_resource_alloc(struct isp_dev *isp) { struct isp_table_addr *tbl = &isp->isp_tbl; - void *pa, *va, *dma; + void *va, *dma; int ret = 0; - isp->isp_stat.size = ISP_STAT_TOTAL_SIZE; - isp->isp_load.size = ISP_LOAD_REG_SIZE; - isp->isp_save.size = ISP_SAVED_REG_SIZE; - + isp->isp_stat.size = ISP_STAT_TOTAL_SIZE + ISP_LOAD_REG_SIZE + ISP_SAVED_REG_SIZE + + ISP_TABLE_MAPPING1_SIZE + ISP_TABLE_MAPPING2_SIZE; ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_stat); if (ret < 0) { vin_err("isp statistic buf requset failed!\n"); return -ENOMEM; } + isp->isp_load.dma_addr = isp->isp_stat.dma_addr + ISP_STAT_TOTAL_SIZE; + isp->isp_load.vir_addr = isp->isp_stat.vir_addr + ISP_STAT_TOTAL_SIZE; + isp->isp_save.dma_addr = isp->isp_load.dma_addr + ISP_LOAD_REG_SIZE; + isp->isp_save.vir_addr = isp->isp_load.vir_addr + ISP_LOAD_REG_SIZE; + isp->isp_lut_tbl.dma_addr = isp->isp_save.dma_addr + ISP_SAVED_REG_SIZE; + isp->isp_lut_tbl.vir_addr = isp->isp_save.vir_addr + ISP_SAVED_REG_SIZE; + isp->isp_drc_tbl.dma_addr = isp->isp_lut_tbl.dma_addr + ISP_TABLE_MAPPING1_SIZE; + isp->isp_drc_tbl.vir_addr = isp->isp_lut_tbl.vir_addr + ISP_TABLE_MAPPING1_SIZE; - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_load); - if (ret < 0) { - vin_err("isp load regs requset failed!\n"); - return -ENOMEM; - } - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_save); - if (ret < 0) { - vin_err("isp save regs requset failed!\n"); - return -ENOMEM; - } - - /*requeset for isp table*/ - isp->isp_lut_tbl.size = ISP_TABLE_MAPPING1_SIZE; - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_lut_tbl); - if (ret < 0) { - vin_err("isp lookup table request failed!\n"); - return -ENOMEM; - } - pa = isp->isp_lut_tbl.phy_addr; va = isp->isp_lut_tbl.vir_addr; dma = isp->isp_lut_tbl.dma_addr; - tbl->isp_lsc_tbl_paddr = (void *)(pa + ISP_LSC_MEM_OFS); tbl->isp_lsc_tbl_dma_addr = (void *)(dma + ISP_LSC_MEM_OFS); tbl->isp_lsc_tbl_vaddr = (void *)(va + ISP_LSC_MEM_OFS); - tbl->isp_gamma_tbl_paddr = (void *)(pa + ISP_GAMMA_MEM_OFS); tbl->isp_gamma_tbl_dma_addr = (void *)(dma + ISP_GAMMA_MEM_OFS); tbl->isp_gamma_tbl_vaddr = (void *)(va + ISP_GAMMA_MEM_OFS); - tbl->isp_linear_tbl_paddr = (void *)(pa + ISP_LINEAR_MEM_OFS); tbl->isp_linear_tbl_dma_addr = (void *)(dma + ISP_LINEAR_MEM_OFS); tbl->isp_linear_tbl_vaddr = (void *)(va + ISP_LINEAR_MEM_OFS); - vin_log(VIN_LOG_ISP, "isp_lsc_tbl_vaddr = %p\n", - tbl->isp_lsc_tbl_vaddr); - vin_log(VIN_LOG_ISP, "isp_gamma_tbl_vaddr = %p\n", - tbl->isp_gamma_tbl_vaddr); - - isp->isp_drc_tbl.size = ISP_TABLE_MAPPING2_SIZE; - ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_drc_tbl); - if (ret < 0) { - vin_err("isp drc table request pa failed!\n"); - return -ENOMEM; - } - pa = isp->isp_drc_tbl.phy_addr; va = isp->isp_drc_tbl.vir_addr; dma = isp->isp_drc_tbl.dma_addr; - tbl->isp_drc_tbl_paddr = (void *)(pa + ISP_DRC_MEM_OFS); tbl->isp_drc_tbl_dma_addr = (void *)(dma + ISP_DRC_MEM_OFS); tbl->isp_drc_tbl_vaddr = (void *)(va + ISP_DRC_MEM_OFS); - vin_log(VIN_LOG_ISP, "isp_drc_tbl_vaddr = %p\n", - tbl->isp_drc_tbl_vaddr); - return ret; - } static void isp_resource_free(struct isp_dev *isp) { os_mem_free(&isp->pdev->dev, &isp->isp_stat); - os_mem_free(&isp->pdev->dev, &isp->isp_load); - os_mem_free(&isp->pdev->dev, &isp->isp_save); - - /* release isp table */ - os_mem_free(&isp->pdev->dev, &isp->isp_lut_tbl); - os_mem_free(&isp->pdev->dev, &isp->isp_drc_tbl); } void isp_isr_bh_handle(struct work_struct *work) @@ -1508,10 +1507,13 @@ static irqreturn_t isp_isr(int irq, void *priv) if (bsp_isp_get_irq_status(isp->id, PARA_LOAD_PD)) { bsp_isp_clr_irq_status(isp->id, PARA_LOAD_PD); - bsp_isp_clr_para_ready(isp->id); + if (isp->ptn_type) { + spin_unlock_irqrestore(&isp->slock, flags); + return IRQ_HANDLED; + } + bsp_isp_set_para_ready(isp->id, PARA_NOT_READY); if (isp->load_flag) memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_REG_SIZE); - load_val = bsp_isp_load_update_flag(isp->id); if (isp->wdr_mode != ISP_NORMAL_MODE) isp_wdr_pingpong_set(isp); @@ -1531,10 +1533,10 @@ static irqreturn_t isp_isr(int irq, void *priv) isp->isp_ob.ob_start.hor += isp->isp_ob.ob_valid.width - LARGE_IMAGE_OFF * 2; } } - bsp_isp_set_ob_zone(isp->id, &isp->isp_ob); + bsp_isp_set_size(isp->id, &isp->isp_ob); bsp_isp_update_table(isp->id, (unsigned short)load_val); - isp_3d_pingpong_update(isp, &isp->isp_3d_buf); - bsp_isp_set_para_ready(isp->id); + isp_3d_pingpong_update(isp); + bsp_isp_set_para_ready(isp->id, PARA_READY); } spin_unlock_irqrestore(&isp->slock, flags); @@ -1542,6 +1544,20 @@ static irqreturn_t isp_isr(int irq, void *priv) bsp_isp_clr_irq_status(isp->id, FINISH_PD); vin_log(VIN_LOG_ISP, "call tasklet schedule!\n"); schedule_work(&isp->isp_isr_bh_task); + + if (isp->ptn_type) { + bsp_isp_set_para_ready(isp->id, PARA_NOT_READY); + memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0] + (isp->ptn_isp_cnt%3) * ISP_LOAD_REG_SIZE, ISP_LOAD_REG_SIZE); + memcpy(isp->isp_lut_tbl.vir_addr, &isp->load_lut_tbl[0] + (isp->ptn_isp_cnt%3) * ISP_TABLE_MAPPING1_SIZE, ISP_TABLE_MAPPING1_SIZE); + memcpy(isp->isp_drc_tbl.vir_addr, &isp->load_drc_tbl[0] + (isp->ptn_isp_cnt%3) * ISP_TABLE_MAPPING2_SIZE, ISP_TABLE_MAPPING2_SIZE); + isp->ptn_isp_cnt++; + load_val = bsp_isp_load_update_flag(isp->id); + bsp_isp_set_size(isp->id, &isp->isp_ob); + bsp_isp_update_table(isp->id, (unsigned short)load_val); + isp_3d_pingpong_update(isp); + bsp_isp_set_para_ready(isp->id, PARA_READY); + } + if (!isp->f1_after_librun) { sunxi_isp_frame_sync_isr(&isp->subdev); if (isp->h3a_stat.stata_en_flag) @@ -1592,11 +1608,6 @@ static int isp_probe(struct platform_device *pdev) isp->base = of_iomap(np, 0); if (!isp->base) { isp->is_empty = 1; - isp->base = kzalloc(0x300, GFP_KERNEL); - if (!isp->base) { - ret = -EIO; - goto freedev; - } } else { isp->is_empty = 0; /*get irq resource */ @@ -1611,6 +1622,12 @@ static int isp_probe(struct platform_device *pdev) vin_err("isp%d request irq failed\n", isp->id); goto unmap; } + if (isp_resource_alloc(isp) < 0) { + ret = -ENOMEM; + goto freeirq; + } + bsp_isp_map_reg_addr(isp->id, (unsigned long)isp->base); + bsp_isp_map_load_dram_addr(isp->id, (unsigned long)isp->isp_load.vir_addr); } list_add_tail(&isp->isp_list, &isp_drv_list); @@ -1618,20 +1635,12 @@ static int isp_probe(struct platform_device *pdev) spin_lock_init(&isp->slock); - if (isp_resource_alloc(isp) < 0) { - ret = -ENOMEM; - goto freeirq; - } - ret = vin_isp_h3a_init(isp); if (ret < 0) { vin_err("VIN H3A initialization failed\n"); goto free_res; } - bsp_isp_init_platform(SUNXI_PLATFORM_ID); - bsp_isp_set_base_addr(isp->id, (unsigned long)isp->base); - bsp_isp_set_map_load_addr(isp->id, (unsigned long)isp->isp_load.vir_addr); platform_set_drvdata(pdev, isp); vin_log(VIN_LOG_ISP, "isp%d probe end!\n", isp->id); return 0; @@ -1662,13 +1671,11 @@ static int isp_remove(struct platform_device *pdev) v4l2_ctrl_handler_free(sd->ctrl_handler); v4l2_set_subdevdata(sd, NULL); - isp_resource_free(isp); if (!isp->is_empty) { + isp_resource_free(isp); free_irq(isp->irq, isp); if (isp->base) iounmap(isp->base); - } else { - kfree(isp->base); } list_del(&isp->isp_list); kfree(isp->stat_buf); @@ -1696,6 +1703,8 @@ void sunxi_isp_sensor_type(struct v4l2_subdev *sd, int use_isp) { struct isp_dev *isp = v4l2_get_subdevdata(sd); isp->use_isp = use_isp; + if (isp->is_empty) + isp->use_isp = 0; } void sunxi_isp_dump_regs(struct v4l2_subdev *sd) @@ -1725,6 +1734,12 @@ void sunxi_isp_debug(struct v4l2_subdev *sd, struct isp_debug_mode *isp_debug) isp->isp_dbg = *isp_debug; } +void sunxi_isp_ptn(struct v4l2_subdev *sd, unsigned int ptn_type) +{ + struct isp_dev *isp = v4l2_get_subdevdata(sd); + isp->ptn_type = ptn_type; +} + struct v4l2_subdev *sunxi_isp_get_subdev(int id) { struct isp_dev *isp; diff --git a/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.h b/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.h index 8a67a26a..be079f12 100644 --- a/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.h +++ b/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.h @@ -17,7 +17,7 @@ #include #include #include "../vin-video/vin_core.h" -#include "bsp_isp.h" +#include "sun8iw12p1/sun8iw12p1_isp_reg_cfg.h" #include "../vin-stat/vin_ispstat.h" #include "../vin-stat/vin_h3a.h" @@ -42,6 +42,20 @@ struct isp_pix_fmt { u16 flags; }; +struct isp_table_addr { + void *isp_lsc_tbl_vaddr; + void *isp_lsc_tbl_dma_addr; + void *isp_gamma_tbl_vaddr; + void *isp_gamma_tbl_dma_addr; + void *isp_linear_tbl_vaddr; + void *isp_linear_tbl_dma_addr; + + void *isp_drc_tbl_vaddr; + void *isp_drc_tbl_dma_addr; + void *isp_saturation_tbl_vaddr; + void *isp_saturation_tbl_dma_addr; +}; + struct sunxi_isp_ctrls { struct v4l2_ctrl_handler handler; @@ -60,17 +74,6 @@ struct isp_stat_to_user { void *pltm_buf; }; -enum isp_3dbuf_flags { - ISP_3D_R = 0, - ISP_3D_W = 1, - ISP_3D_MAX = 2, -}; - -struct isp_hw_pingpong { - struct vin_mm buf[ISP_3D_MAX]; - int flags[ISP_3D_MAX]; -}; - struct isp_dev { int use_cnt; struct v4l2_subdev subdev; @@ -83,18 +86,22 @@ struct isp_dev { int use_isp; int irq; unsigned int is_empty; + unsigned int ptn_isp_cnt; unsigned int load_flag; unsigned int f1_after_librun;/*fisrt frame after server run*/ unsigned int have_init; unsigned int wdr_mode; unsigned int large_image;/*2:get merge yuv, 1: get pattern raw (save in kernel), 0: normal*/ unsigned int left_right;/*0: process left, 1: process right*/ + unsigned int ptn_type; unsigned int id; spinlock_t slock; struct mutex subdev_lock; struct work_struct isp_isr_bh_task; void __iomem *base; - char load_shadow[ISP_LOAD_REG_SIZE]; + char load_shadow[ISP_LOAD_REG_SIZE*3]; + char load_lut_tbl[ISP_TABLE_MAPPING1_SIZE*3]; + char load_drc_tbl[ISP_TABLE_MAPPING2_SIZE*3]; struct vin_mm isp_stat; struct vin_mm isp_load; struct vin_mm isp_save; @@ -107,7 +114,7 @@ struct isp_dev { struct isp_size_settings isp_ob; struct v4l2_mbus_framefmt mf; struct isp_stat h3a_stat; - struct isp_hw_pingpong isp_3d_buf; + struct vin_mm d3d_pingpong[2]; struct vin_mm wdr_pingpong[2]; }; @@ -116,6 +123,7 @@ void isp_isr_bh_handle(struct work_struct *work); void sunxi_isp_sensor_type(struct v4l2_subdev *sd, int use_isp); void sunxi_isp_dump_regs(struct v4l2_subdev *sd); void sunxi_isp_debug(struct v4l2_subdev *sd, struct isp_debug_mode *isp_debug); +void sunxi_isp_ptn(struct v4l2_subdev *sd, unsigned int ptn_type); void sunxi_isp_vsync_isr(struct v4l2_subdev *sd); void sunxi_isp_frame_sync_isr(struct v4l2_subdev *sd); struct v4l2_subdev *sunxi_isp_get_subdev(int id); diff --git a/drivers/media/platform/sunxi-vin/vin-mipi/sunxi_mipi.c b/drivers/media/platform/sunxi-vin/vin-mipi/sunxi_mipi.c index 86f05221..be4975e6 100644 --- a/drivers/media/platform/sunxi-vin/vin-mipi/sunxi_mipi.c +++ b/drivers/media/platform/sunxi-vin/vin-mipi/sunxi_mipi.c @@ -66,6 +66,30 @@ static struct combo_format sunxi_mipi_formats[] = { }, { .code = MEDIA_BUS_FMT_SRGGB12_1X12, .bit_width = RAW12, + }, { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .bit_width = RAW8, + }, { + .code = MEDIA_BUS_FMT_VYUY8_2X8, + .bit_width = RAW8, + }, { + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .bit_width = RAW8, + }, { + .code = MEDIA_BUS_FMT_YVYU8_2X8, + .bit_width = RAW8, + }, { + .code = MEDIA_BUS_FMT_UYVY10_2X10, + .bit_width = RAW10, + }, { + .code = MEDIA_BUS_FMT_VYUY10_2X10, + .bit_width = RAW10, + }, { + .code = MEDIA_BUS_FMT_YUYV10_2X10, + .bit_width = RAW10, + }, { + .code = MEDIA_BUS_FMT_YVYU10_2X10, + .bit_width = RAW10, } }; @@ -257,8 +281,15 @@ static enum pkt_fmt get_pkt_fmt(u32 code) case MEDIA_BUS_FMT_RGB565_2X8_BE: return MIPI_RGB565; case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: return MIPI_YUV422; + case MEDIA_BUS_FMT_UYVY10_2X10: + case MEDIA_BUS_FMT_VYUY10_2X10: case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YVYU10_2X10: return MIPI_YUV422_10; case MEDIA_BUS_FMT_SBGGR8_1X8: case MEDIA_BUS_FMT_SGBRG8_1X8: diff --git a/drivers/media/platform/sunxi-vin/vin-stat/vin_ispstat.c b/drivers/media/platform/sunxi-vin/vin-stat/vin_ispstat.c index 5b899cd9..f8979598 100644 --- a/drivers/media/platform/sunxi-vin/vin-stat/vin_ispstat.c +++ b/drivers/media/platform/sunxi-vin/vin-stat/vin_ispstat.c @@ -152,7 +152,7 @@ static void isp_stat_bufs_free(struct isp_stat *stat) { int i; - for (i = 0; i < STAT_MAX_BUFS; i++) { + for (i = 1; i < STAT_MAX_BUFS; i++) { struct ispstat_buffer *buf = &stat->buf[i]; struct vin_mm *mm = &stat->ion_man[i]; mm->size = stat->buf_alloc_size; @@ -183,7 +183,7 @@ static int isp_stat_bufs_alloc_dma(struct isp_stat *stat, unsigned int size) stat->buf_alloc_size = size; - for (i = 0; i < STAT_MAX_BUFS; i++) { + for (i = 1; i < STAT_MAX_BUFS; i++) { struct ispstat_buffer *buf = &stat->buf[i]; struct vin_mm *mm = &stat->ion_man[i]; mm->size = stat->buf_alloc_size; @@ -199,7 +199,6 @@ static int isp_stat_bufs_alloc_dma(struct isp_stat *stat, unsigned int size) return -ENOMEM; } buf->empty = 1; - memset(buf->virt_addr, 0, stat->buf_alloc_size); vin_log(VIN_LOG_STAT, "%s: buffer[%d] allocated." "dma_addr=0x%08lx virt_addr=0x%08lx\n", diff --git a/drivers/media/platform/sunxi-vin/vin-video/dma_reg.h b/drivers/media/platform/sunxi-vin/vin-video/dma_reg.h index c3164097..605841db 100644 --- a/drivers/media/platform/sunxi-vin/vin-video/dma_reg.h +++ b/drivers/media/platform/sunxi-vin/vin-video/dma_reg.h @@ -109,7 +109,7 @@ enum dma_int_sel { DMA_INT_VSYNC_TRIG = 0X80, DMA_INT_FBC_OVHD_WRDDR_FULL = 0X100, DMA_INT_FBC_DATA_WRDDR_FULL = 0X200, - DMA_INT_ALL = 0XFF, + DMA_INT_ALL = 0X3FF, }; /*register data struct*/ diff --git a/drivers/media/platform/sunxi-vin/vin-video/dma_reg_i.h b/drivers/media/platform/sunxi-vin/vin-video/dma_reg_i.h index 4bd871f8..3ae68674 100644 --- a/drivers/media/platform/sunxi-vin/vin-video/dma_reg_i.h +++ b/drivers/media/platform/sunxi-vin/vin-video/dma_reg_i.h @@ -48,15 +48,15 @@ #define CSIC_DMA_HSIZE_REG_OFF 0X010 #define HOR_START 0 -#define HOR_START_MASK (0X1FFF << HOR_START) +#define HOR_START_MASK (0X3FFF << HOR_START) #define HOR_LEN 16 -#define HOR_LEN_MASK (0X1FFF << HOR_LEN) +#define HOR_LEN_MASK (0X3FFF << HOR_LEN) #define CSIC_DMA_VSIZE_REG_OFF 0X014 #define VER_START 0 -#define VER_START_MASK (0X1FFF << VER_START) +#define VER_START_MASK (0X3FFF << VER_START) #define VER_LEN 16 -#define VER_LEN_MASK (0X1FFF << VER_LEN) +#define VER_LEN_MASK (0X3FFF << VER_LEN) #define CSIC_DMA_F0_BUFA_REG_OFF 0X020 #define F0_BUFA 0 @@ -78,9 +78,9 @@ #define CSIC_DMA_FLIP_SIZE_REG_OFF 0X03C #define VALID_LEN 0 -#define VALID_LEN_MASK (0X1FFF << VALID_LEN) +#define VALID_LEN_MASK (0X3FFF << VALID_LEN) #define VER_LEN 16 -#define VER_LEN_MASK (0X1FFF << VER_LEN) +#define VER_LEN_MASK (0X3FFF << VER_LEN) #define CSIC_DMA_CAP_STA_REG_OFF 0X04C #define SCAP_STA 0 diff --git a/drivers/media/platform/sunxi-vin/vin-video/vin_core.c b/drivers/media/platform/sunxi-vin/vin-video/vin_core.c index a4a4342a..a8a65bd2 100644 --- a/drivers/media/platform/sunxi-vin/vin-video/vin_core.c +++ b/drivers/media/platform/sunxi-vin/vin-video/vin_core.c @@ -71,6 +71,7 @@ size_t vi_status_size_sum; uint isp_reparse_flag; uint vin_dump; +uint ptn_frame_cnt; #define DEVICE_ATTR_SHOW(name) \ static ssize_t name##_show(struct device *dev, \ @@ -159,7 +160,7 @@ static struct vin_fmt vin_formats[] = { .color = V4L2_COLORSPACE_JPEG, .memplanes = 1, .colplanes = 3, - .flags = VIN_FMT_YUV, + .flags = VIN_FMT_YUV | VIN_FMT_RAW, }, { .name = "YUV 4:2:2 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV16, @@ -168,6 +169,14 @@ static struct vin_fmt vin_formats[] = { .memplanes = 1, .colplanes = 2, .flags = VIN_FMT_YUV | VIN_FMT_RAW, + }, { + .name = "YUV 4:2:2 planar, Y/CbCr", + .fourcc = V4L2_PIX_FMT_NV16M, + .depth = { 8, 8 }, + .color = V4L2_COLORSPACE_JPEG, + .memplanes = 2, + .colplanes = 2, + .flags = VIN_FMT_YUV | VIN_FMT_RAW, }, { .name = "YUV 4:2:2 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV61, @@ -176,6 +185,14 @@ static struct vin_fmt vin_formats[] = { .memplanes = 1, .colplanes = 2, .flags = VIN_FMT_YUV | VIN_FMT_RAW, + }, { + .name = "YUV 4:2:2 planar, Y/CrCb", + .fourcc = V4L2_PIX_FMT_NV61M, + .depth = { 8, 8 }, + .color = V4L2_COLORSPACE_JPEG, + .memplanes = 2, + .colplanes = 2, + .flags = VIN_FMT_YUV | VIN_FMT_RAW, }, { .name = "YUV 4:2:0 planar, YCbCr", .fourcc = V4L2_PIX_FMT_YUV420, @@ -905,6 +922,7 @@ static irqreturn_t vin_isr(int irq, void *priv) struct dma_output_size size; struct csic_dma_flip flip; struct list_head *buf_next = NULL; + struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev); if (vin_streaming(cap) == 0) { csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL); @@ -920,7 +938,7 @@ static irqreturn_t vin_isr(int irq, void *priv) if (9 == (vinc->vin_status.frame_cnt % 10)) sunxi_isp_dump_regs(vinc->vid_cap.pipe.sd[VIN_IND_ISP]); - mod_timer(&vinc->timer_for_reset, jiffies + 2*HZ); + mod_timer(&vinc->timer_for_reset, jiffies + (2 + vinc->vin_reset_time) * HZ); spin_lock_irqsave(&cap->slock, flags); @@ -950,22 +968,18 @@ static irqreturn_t vin_isr(int irq, void *priv) csic_dma_disable(vinc->vipp_sel); csic_dma_enable(vinc->vipp_sel); } - goto unlock; } if (status.fbc_ovhd_wrddr_full) { csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_FBC_OVHD_WRDDR_FULL); /*when open isp debug please ignore fbc error!*/ - if (!vinc->isp_dbg.debug_en) { + if (!vinc->isp_dbg.debug_en) vin_err("video%d fbc overhead write ddr full\n", vinc->id); - goto unlock; - } } if (status.fbc_data_wrddr_full) { csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_FBC_DATA_WRDDR_FULL); vin_err("video%d fbc data write ddr full\n", vinc->id); - goto unlock; } if (status.vsync_trig) { @@ -981,15 +995,26 @@ static irqreturn_t vin_isr(int irq, void *priv) size.hor_start = 32; csic_dma_output_size_cfg(vinc->vipp_sel, &size); } - goto unlock; - } - - /*when open isp debug line count interrupt would not come!*/ - if (status.line_cnt_flag) { - csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_LINE_CNT); if (cap->capture_mode != V4L2_MODE_IMAGE) { - if (list_empty(&cap->vidq_active) || - cap->vidq_active.next->next == &cap->vidq_active) { + if (cap->first_flag && vinc->large_image != 2) { + if ((&cap->vidq_active) == cap->vidq_active.next->next->next) { + vin_log(VIN_LOG_VIDEO, "Only two buffer left for video%d\n", vinc->id); + vinc->vin_status.lost_cnt++; + goto unlock; + } + if (vinc->vflip_delay == 1) { + vinc->vflip_delay--; + goto unlock; + } + buf = list_entry(cap->vidq_active.next, struct vin_buffer, list); + buf->vb.sequence = csic_dma_get_frame_cnt(vinc->vipp_sel); + buf->vb.framecnt = vinc->vin_status.frame_cnt; + buf->vb.exp_time = sensor_get_exp(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR]); + v4l2_get_timestamp(&buf->vb.timestamp); + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + if (list_empty(&cap->vidq_active) || cap->vidq_active.next->next == &cap->vidq_active) { vin_log(VIN_LOG_VIDEO, "No active queue to serve\n"); goto unlock; } @@ -1009,21 +1034,42 @@ static irqreturn_t vin_isr(int irq, void *priv) vinc->vflip_delay--; } } - goto unlock; + if (cap->first_flag == 0) { + cap->first_flag++; + vin_log(VIN_LOG_VIDEO, "video%d first frame!\n", vinc->id); + } + } + + /*when open isp debug line count interrupt would not come!*/ + if (status.line_cnt_flag) { + csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_LINE_CNT); + vin_log(VIN_LOG_VIDEO, "video%d line_cnt interrupt!\n", vinc->id); } if (cap->capture_mode == V4L2_MODE_IMAGE && status.capture_done) { - csic_dma_int_disable(vinc->vipp_sel, DMA_INT_CAPTURE_DONE); + csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_CAPTURE_DONE); vin_log(VIN_LOG_VIDEO, "capture image mode!\n"); buf = list_entry(cap->vidq_active.next, struct vin_buffer, list); + v4l2_get_timestamp(&buf->vb.timestamp); list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); - goto unlock; } else if (status.frame_done) { int fps = 30; - csic_dma_int_disable(vinc->vipp_sel, DMA_INT_FRAME_DONE); - if (vinc->ptn_cfg.ptn_en) - csic_ptn_generation_en(0, 1); + csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_FRAME_DONE); + if (vinc->ptn_cfg.ptn_en) { + if (vinc->ptn_cfg.ptn_type > 0) { + ptn_frame_cnt++; + if (ptn_frame_cnt%(vinc->ptn_cfg.ptn_type) == 0) { + if (ptn_frame_cnt/(vinc->ptn_cfg.ptn_type) < 3) + csic_ptn_addr(vind->id, (unsigned long)(vinc->ptn_cfg.ptn_buf.dma_addr)); + else + csic_ptn_addr(vind->id, (unsigned long)(vinc->ptn_cfg.ptn_buf.dma_addr + (ptn_frame_cnt/vinc->ptn_cfg.ptn_type-2)%3 * vinc->ptn_cfg.ptn_buf.size / 3)); + csic_ptn_generation_en(0, 1); + } + } else { + csic_ptn_generation_en(0, 1); + } + } vinc->vin_status.buf_rest = 2; buf_next = cap->vidq_active.next->next->next; @@ -1034,13 +1080,18 @@ static irqreturn_t vin_isr(int irq, void *priv) break; } + if (list_empty(&cap->vidq_active) || cap->vidq_active.next->next == &cap->vidq_active) { + vin_log(VIN_LOG_VIDEO, "No active queue to serve\n"); + goto unlock; + } + /* video buffer handle */ if ((&cap->vidq_active) == cap->vidq_active.next->next->next) { vin_log(VIN_LOG_VIDEO, "Only two buffer left for video%d\n", vinc->id); v4l2_get_timestamp(&cap->ts); - vinc->vin_status.lost_cnt++; goto unlock; } + buf = list_entry(cap->vidq_active.next, struct vin_buffer, list); /* Nobody is waiting on this buffer */ @@ -1064,23 +1115,12 @@ static irqreturn_t vin_isr(int irq, void *priv) } } cap->ts = buf->vb.timestamp; - buf->vb.sequence = csic_dma_get_frame_cnt(vinc->vipp_sel); - buf->vb.framecnt = vinc->vin_status.frame_cnt; - buf->vb.exp_time = sensor_get_exp(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR]); - - if (vinc->vflip_delay == 1) { - vinc->vflip_delay--; - goto unlock; - } if (vinc->large_image == 2) { if (vinc->vin_status.frame_cnt % 2 == 0) { list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } - } else { - list_del(&buf->list); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } if (cap->osd.overlay_en && !(vinc->vin_status.frame_cnt % (fps / 5))) { @@ -1101,37 +1141,11 @@ static irqreturn_t vin_isr(int irq, void *priv) } vipp_osd_inverse(vinc->vipp_sel, inverse, cap->osd.overlay_cnt); } - - if (cap->first_flag == 0) { - cap->first_flag++; - vin_log(VIN_LOG_VIDEO, "video%d first frame done!\n", vinc->id); - } - - /*when open isp debug buffer addr should update in finish interrupt!*/ - if (vinc->isp_dbg.debug_en) { - if (list_empty(&cap->vidq_active) || cap->vidq_active.next->next == &cap->vidq_active) { - vin_log(VIN_LOG_VIDEO, "No active queue to serve\n"); - goto unlock; - } - if (vinc->large_image == 1) - csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, (unsigned long)vinc->ptn_cfg.ptn_buf.dma_addr); - else if ((vinc->large_image == 2) && (vinc->vin_status.frame_cnt % 2)) { - buf = list_entry(cap->vidq_active.next, struct vin_buffer, list); - vin_set_addr(vinc, &buf->vb.vb2_buf, &vinc->vid_cap.frame, &vinc->vid_cap.frame.paddr); - } else { - buf = list_entry(cap->vidq_active.next->next, struct vin_buffer, list); - vin_set_addr(vinc, &buf->vb.vb2_buf, &vinc->vid_cap.frame, &vinc->vid_cap.frame.paddr); - } - } } unlock: spin_unlock_irqrestore(&cap->slock, flags); - csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL); - if (cap->capture_mode != V4L2_MODE_IMAGE) - csic_dma_int_enable(vinc->vipp_sel, DMA_INT_ALL); - return IRQ_HANDLED; #endif } diff --git a/drivers/media/platform/sunxi-vin/vin-video/vin_core.h b/drivers/media/platform/sunxi-vin/vin-video/vin_core.h index cb6f9754..1944fc2d 100644 --- a/drivers/media/platform/sunxi-vin/vin-video/vin_core.h +++ b/drivers/media/platform/sunxi-vin/vin-video/vin_core.h @@ -31,7 +31,6 @@ #include "../modules/actuator/actuator.h" #include "../vin-csi/bsp_csi.h" #include "../vin-mipi/bsp_mipi_csi.h" -#include "../vin-isp/bsp_isp.h" #include "../utility/vin_supply.h" #include "vin_video.h" #include "../vin.h" @@ -73,6 +72,7 @@ struct vin_ptn_cfg { __u32 ptn_h; __u32 ptn_mode; __u32 ptn_dw; + __u32 ptn_type; struct vin_mm ptn_buf; }; @@ -110,6 +110,7 @@ struct vin_core { int irq; struct vin_status_info vin_status; struct timer_list timer_for_reset; + unsigned int vin_reset_time; struct vin_ptn_cfg ptn_cfg; }; diff --git a/drivers/media/platform/sunxi-vin/vin-video/vin_video.c b/drivers/media/platform/sunxi-vin/vin-video/vin_video.c index 0fa80304..f4c32b1c 100644 --- a/drivers/media/platform/sunxi-vin/vin-video/vin_video.c +++ b/drivers/media/platform/sunxi-vin/vin-video/vin_video.c @@ -150,13 +150,14 @@ int vin_set_addr(struct vin_core *vinc, struct vb2_buffer *vb, paddr->cb += CEIL_EXP(frame->o_width, 4) * (CEIL_EXP(frame->o_height, 2) - 1) * 96; paddr->cr = 0; } else if (vinc->vflip == 1) { - paddr->y += pix_size - frame->o_width * frame->fmt.depth[0] / 8; switch (frame->fmt.colplanes) { case 1: + paddr->y += (pix_size - frame->o_width) * frame->fmt.depth[0] / 8; paddr->cb = 0; paddr->cr = 0; break; case 2: + paddr->y += pix_size - frame->o_width; /* 420 */ if (12 == depth) paddr->cb += pix_size / 2 - frame->o_width; @@ -165,6 +166,7 @@ int vin_set_addr(struct vin_core *vinc, struct vb2_buffer *vb, paddr->cr = 0; break; case 3: + paddr->y += pix_size - frame->o_width; if (12 == depth) { paddr->cb += pix_size / 4 - frame->o_width / 2; paddr->cr += pix_size / 4 - frame->o_width / 2; @@ -1704,6 +1706,35 @@ static int isp_exif_req(struct file *file, struct v4l2_fh *fh, return 0; } +static int __vin_sensor_line2time(struct v4l2_subdev *sd, u32 exp_line) +{ + struct sensor_info *info = to_state(sd); + u32 overflow = 0xffffffff / 1000000, pclk = 0; + int exp_time = 0; + + if ((exp_line / 16) > overflow) { + exp_line = exp_line / 16; + pclk = info->current_wins->pclk / 1000000; + } else if ((exp_line / 16) > (overflow / 10)) { + exp_line = exp_line * 10 / 16; + pclk = info->current_wins->pclk / 100000; + } else if ((exp_line / 16) > (overflow / 100)) { + exp_line = exp_line * 100 / 16; + pclk = info->current_wins->pclk / 10000; + } else if ((exp_line / 16) > (overflow / 1000)) { + exp_line = exp_line * 1000 / 16; + pclk = info->current_wins->pclk / 1000; + } else { + exp_line = exp_line * 10000 / 16; + pclk = info->current_wins->pclk / 100; + } + + if (pclk) + exp_time = exp_line * info->current_wins->hts / pclk; + + return exp_time; +} + static int __vin_sensor_set_af_win(struct vin_vid_cap *cap) { struct vin_pipeline *pipe = &cap->pipe; @@ -1822,7 +1853,8 @@ static int vidioc_vin_ptn_config(struct file *file, struct v4l2_fh *fh, vinc->ptn_cfg.ptn_h = ptn->ptn_h; vinc->ptn_cfg.ptn_mode = 12; vinc->ptn_cfg.ptn_buf.size = ptn->ptn_size; - + vinc->ptn_cfg.ptn_type = ptn->ptn_type; + sunxi_isp_ptn(vinc->vid_cap.pipe.sd[VIN_IND_ISP], vinc->ptn_cfg.ptn_type); switch (ptn->ptn_fmt) { case V4L2_PIX_FMT_SBGGR8: case V4L2_PIX_FMT_SGBRG8: @@ -1874,6 +1906,16 @@ static int vidioc_vin_ptn_config(struct file *file, struct v4l2_fh *fh, return 0; } +static int vidioc_vin_set_reset_time(struct file *file, struct v4l2_fh *fh, + struct vin_reset_time *time) +{ + struct vin_core *vinc = video_drvdata(file); + + vinc->vin_reset_time = time->reset_time; + + return 0; +} + static long vin_param_handler(struct file *file, void *priv, bool valid_prio, unsigned int cmd, void *param) { @@ -1902,6 +1944,9 @@ static long vin_param_handler(struct file *file, void *priv, case VIDIOC_VIN_PTN_CFG: ret = vidioc_vin_ptn_config(file, fh, param); break; + case VIDIOC_VIN_RESET_TIME: + ret = vidioc_vin_set_reset_time(file, fh, param); + break; default: ret = -ENOTTY; } @@ -1988,20 +2033,65 @@ static int vin_close(struct file *file) return 0; } +static int vin_try_ctrl(struct v4l2_ctrl *ctrl) +{ + /* + * to cheat control framework, because of when ctrl->cur.val == ctrl->val + * s_ctrl would not be called + */ + if ((ctrl->minimum == 0) && (ctrl->maximum == 1)) { + if (ctrl->val) + ctrl->cur.val = 0; + else + ctrl->cur.val = 1; + } else { + if (ctrl->val == ctrl->maximum) + ctrl->cur.val = ctrl->val - 1; + else + ctrl->cur.val = ctrl->val + 1; + } + + /* + * to cheat control framework, because of when ctrl->flags is + * V4L2_CTRL_FLAG_VOLATILE, s_ctrl would not be called + */ + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + case V4L2_CID_EXPOSURE_ABSOLUTE: + case V4L2_CID_GAIN: + if (ctrl->val != ctrl->cur.val) + ctrl->flags &= ~V4L2_CTRL_FLAG_VOLATILE; + break; + default: + break; + } + return 0; +} static int vin_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { - int ret = 0; - struct vin_vid_cap *cap = - container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler); - struct vin_core *vinc = cap->vinc; - struct sensor_instance *inst = get_valid_sensor(vinc); + struct vin_vid_cap *cap = container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler); + struct sensor_instance *inst = get_valid_sensor(cap->vinc); + struct v4l2_subdev *sensor = cap->pipe.sd[VIN_IND_SENSOR]; + struct v4l2_subdev *flash = cap->pipe.sd[VIN_IND_FLASH]; struct v4l2_control c; - c.id = ctrl->id; + int ret = 0; + c.id = ctrl->id; if (inst->is_isp_used && inst->is_bayer_raw) { switch (ctrl->id) { case V4L2_CID_EXPOSURE: + v4l2_subdev_call(sensor, core, g_ctrl, &c); + ctrl->val = c.value; + break; + case V4L2_CID_EXPOSURE_ABSOLUTE: + c.id = V4L2_CID_EXPOSURE; + v4l2_subdev_call(sensor, core, g_ctrl, &c); + ctrl->val = __vin_sensor_line2time(sensor, c.value); + break; case V4L2_CID_GAIN: + v4l2_subdev_call(sensor, core, g_ctrl, &c); + ctrl->val = c.value; + break; case V4L2_CID_HOR_VISUAL_ANGLE: case V4L2_CID_VER_VISUAL_ANGLE: case V4L2_CID_FOCUS_LENGTH: @@ -2021,21 +2111,15 @@ static int vin_g_volatile_ctrl(struct v4l2_ctrl *ctrl) c.value = inst->is_bayer_raw; break; case V4L2_CID_FLASH_LED_MODE: - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_FLASH], - core, g_ctrl, &c); + ret = v4l2_subdev_call(flash, core, g_ctrl, &c); break; case V4L2_CID_AUTO_FOCUS_STATUS: - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, g_ctrl, &c); + ret = v4l2_subdev_call(sensor, core, g_ctrl, &c); if (c.value != V4L2_AUTO_FOCUS_STATUS_BUSY) - sunxi_flash_stop(cap->pipe.sd[VIN_IND_FLASH]); + sunxi_flash_stop(flash); break; default: - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, g_ctrl, &c); + ret = v4l2_subdev_call(sensor, core, g_ctrl, &c); break; } ctrl->val = c.value; @@ -2047,10 +2131,11 @@ static int vin_g_volatile_ctrl(struct v4l2_ctrl *ctrl) static int vin_s_ctrl(struct v4l2_ctrl *ctrl) { - struct vin_vid_cap *cap = - container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler); - struct vin_core *vinc = cap->vinc; - struct sensor_instance *inst = get_valid_sensor(vinc); + struct vin_vid_cap *cap = container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler); + struct sensor_instance *inst = get_valid_sensor(cap->vinc); + struct v4l2_subdev *sensor = cap->pipe.sd[VIN_IND_SENSOR]; + struct v4l2_subdev *flash = cap->pipe.sd[VIN_IND_FLASH]; + struct v4l2_subdev *act = cap->pipe.sd[VIN_IND_ACTUATOR]; struct csic_dma_flip flip; struct actuator_ctrl_word_t vcm_ctrl; struct v4l2_control c; @@ -2061,20 +2146,34 @@ static int vin_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_VFLIP: - if (vinc->vid_cap.first_flag) - vinc->vflip_delay = 2; - vinc->vflip = c.value; + if (cap->first_flag) + cap->vinc->vflip_delay = 2; + cap->vinc->vflip = c.value; return ret; case V4L2_CID_HFLIP: - vinc->hflip = c.value; - flip.hflip_en = vinc->hflip; - flip.vflip_en = vinc->vflip; - csic_dma_flip_en(vinc->vipp_sel, &flip); + cap->vinc->hflip = c.value; + flip.hflip_en = cap->vinc->hflip; + flip.vflip_en = cap->vinc->vflip; + csic_dma_flip_en(cap->vinc->vipp_sel, &flip); return ret; default: break; } + /* + * make sure g_ctrl will get the value that hardware is using + * so that ctrl->flags should be V4L2_CTRL_FLAG_VOLATILE, after s_ctrl + */ + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + case V4L2_CID_EXPOSURE_ABSOLUTE: + case V4L2_CID_GAIN: + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + break; + default: + break; + } + if (inst->is_isp_used && inst->is_bayer_raw) { switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -2129,28 +2228,18 @@ static int vin_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_FOCUS_ABSOLUTE: vcm_ctrl.code = ctrl->val; vcm_ctrl.sr = 0x0; - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_ACTUATOR], - core, ioctl, - ACT_SET_CODE, &vcm_ctrl); + ret = v4l2_subdev_call(act, core, ioctl, ACT_SET_CODE, &vcm_ctrl); break; case V4L2_CID_FLASH_LED_MODE: - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_FLASH], - core, s_ctrl, &c); + ret = v4l2_subdev_call(flash, core, s_ctrl, &c); break; case V4L2_CID_AUTO_FOCUS_START: - sunxi_flash_check_to_start(cap->pipe.sd[VIN_IND_FLASH], - SW_CTRL_TORCH_ON); - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, s_ctrl, &c); + sunxi_flash_check_to_start(flash, SW_CTRL_TORCH_ON); + ret = v4l2_subdev_call(sensor, core, s_ctrl, &c); break; case V4L2_CID_AUTO_FOCUS_STOP: - sunxi_flash_stop(cap->pipe.sd[VIN_IND_FLASH]); - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, s_ctrl, &c); + sunxi_flash_stop(flash); + ret = v4l2_subdev_call(sensor, core, s_ctrl, &c); break; case V4L2_CID_AE_WIN_X1: ret = __vin_sensor_set_ae_win(cap); @@ -2160,14 +2249,10 @@ static int vin_s_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_AUTO_EXPOSURE_BIAS: c.value = ctrl->qmenu_int[ctrl->val]; - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, s_ctrl, &c); + ret = v4l2_subdev_call(sensor, core, s_ctrl, &c); break; default: - ret = - v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], - core, s_ctrl, &c); + ret = v4l2_subdev_call(sensor, core, s_ctrl, &c); break; } } @@ -2192,6 +2277,7 @@ static long vin_compat_ioctl32(struct file *file, unsigned int cmd, static const struct v4l2_ctrl_ops vin_ctrl_ops = { .g_volatile_ctrl = vin_g_volatile_ctrl, .s_ctrl = vin_s_ctrl, + .try_ctrl = vin_try_ctrl, }; static const struct v4l2_file_operations vin_fops = { @@ -2422,21 +2508,18 @@ int vin_init_controls(struct v4l2_ctrl_handler *hdl, struct vin_vid_cap *cap) v4l2_ctrl_handler_init(hdl, 40 + ARRAY_SIZE(custom_ctrls) + ARRAY_SIZE(ae_win_ctrls) + ARRAY_SIZE(af_win_ctrls)); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BRIGHTNESS, -128, 128, 1, - 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BRIGHTNESS, -128, 128, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_CONTRAST, -128, 128, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_SATURATION, -256, 512, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, - 1, 1); - ctrl = - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE, 0, - 65536 * 16, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); + ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE, 1, 65536 * 16, 1, 1); if (ctrl != NULL) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_GAIN, 1 * 1600, - 256 * 1600, 1, 1 * 1600); + ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_GAIN, 16, 6000 * 16, 1, 16); + if (ctrl != NULL) + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); @@ -2446,32 +2529,24 @@ int vin_init_controls(struct v4l2_ctrl_handler *hdl, struct vin_vid_cap *cap) V4L2_CID_POWER_LINE_FREQUENCY_AUTO); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HUE_AUTO, 0, 1, 1, 1); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, - V4L2_CID_WHITE_BALANCE_TEMPERATURE, 2800, 10000, 1, - 6500); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_SHARPNESS, -32, 32, 1, - 0); + V4L2_CID_WHITE_BALANCE_TEMPERATURE, 2800, 10000, 1, 6500); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_SHARPNESS, -32, 32, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_CHROMA_AGC, 0, 1, 1, 1); v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR, 0, V4L2_COLORFX_NONE); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, - 1); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BAND_STOP_FILTER, 0, 1, - 1, 1); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, - 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, - 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BAND_STOP_FILTER, 0, 1, 1, 1); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_APERTURE_PRIORITY, 0, V4L2_EXPOSURE_AUTO); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, - 1000000, 1, 1); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_AUTO_PRIORITY, - 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 127, - 1, 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_RELATIVE, -127, - 127, 1, 0); + ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, 30 * 1000000, 1, 1); + if (ctrl != NULL) + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_AUTO_PRIORITY, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 127, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_RELATIVE, -127, 127, 1, 0); v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_AUTO, 0, 1, 1, 1); v4l2_ctrl_new_int_menu(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS, ARRAY_SIZE(exp_bias_qmenu) - 1, @@ -2480,10 +2555,8 @@ int vin_init_controls(struct v4l2_ctrl_handler *hdl, struct vin_vid_cap *cap) V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, V4L2_WHITE_BALANCE_SHADE, 0, V4L2_WHITE_BALANCE_AUTO); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, - 1, 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_IMAGE_STABILIZATION, 0, - 1, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0); v4l2_ctrl_new_int_menu(hdl, &vin_ctrl_ops, V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1, ARRAY_SIZE(iso_qmenu) / 2 - 1, iso_qmenu); @@ -2497,17 +2570,12 @@ int vin_init_controls(struct v4l2_ctrl_handler *hdl, struct vin_vid_cap *cap) V4L2_EXPOSURE_METERING_AVERAGE); v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_TEXT, 0, V4L2_SCENE_MODE_NONE); - ctrl = - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_3A_LOCK, 0, 7, 0, 0); + ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_3A_LOCK, 0, 7, 0, 0); if (ctrl != NULL) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_START, 0, 0, - 0, 0); - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STOP, 0, 0, 0, - 0); - ctrl = - v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STATUS, 0, - 7, 0, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_START, 0, 0, 0, 0); + v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STOP, 0, 0, 0, 0); + ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STATUS, 0, 7, 0, 0); if (ctrl != NULL) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_RANGE, @@ -2727,13 +2795,20 @@ static int vin_subdev_s_stream(struct v4l2_subdev *sd, int enable) buf_len.buf_len_y = cap->frame.o_width; buf_len.buf_len_c = buf_len.buf_len_y >> 1; break; + case V4L2_PIX_FMT_YUV422P: + cfg.fmt = flag ? FRAME_PLANAR_YUV422 : FIELD_PLANAR_YUV422; + buf_len.buf_len_y = cap->frame.o_width; + buf_len.buf_len_c = buf_len.buf_len_y >> 1; + break; case V4L2_PIX_FMT_NV61: - cfg.fmt = flag ? FRAME_UV_CB_YUV422 : FIELD_UV_CB_YUV422; + case V4L2_PIX_FMT_NV61M: + cfg.fmt = flag ? FRAME_VU_CB_YUV422 : FIELD_VU_CB_YUV422; buf_len.buf_len_y = cap->frame.o_width; buf_len.buf_len_c = buf_len.buf_len_y; break; case V4L2_PIX_FMT_NV16: - cfg.fmt = flag ? FRAME_VU_CB_YUV422 : FIELD_VU_CB_YUV422; + case V4L2_PIX_FMT_NV16M: + cfg.fmt = flag ? FRAME_UV_CB_YUV422 : FIELD_UV_CB_YUV422; buf_len.buf_len_y = cap->frame.o_width; buf_len.buf_len_c = buf_len.buf_len_y; break; @@ -2750,6 +2825,7 @@ static int vin_subdev_s_stream(struct v4l2_subdev *sd, int enable) case V4L2_PIX_FMT_SGBRG10: case V4L2_PIX_FMT_SGRBG10: case V4L2_PIX_FMT_SRGGB10: + flip_mul = 1; cfg.fmt = flag ? FRAME_RAW_10 : FIELD_RAW_10; buf_len.buf_len_y = cap->frame.o_width * 2; buf_len.buf_len_c = buf_len.buf_len_y; @@ -2758,6 +2834,7 @@ static int vin_subdev_s_stream(struct v4l2_subdev *sd, int enable) case V4L2_PIX_FMT_SGBRG12: case V4L2_PIX_FMT_SGRBG12: case V4L2_PIX_FMT_SRGGB12: + flip_mul = 1; cfg.fmt = flag ? FRAME_RAW_12 : FIELD_RAW_12; buf_len.buf_len_y = cap->frame.o_width * 2; buf_len.buf_len_c = buf_len.buf_len_y; @@ -2811,14 +2888,19 @@ static int vin_subdev_s_stream(struct v4l2_subdev *sd, int enable) csic_dma_buffer_length(vinc->vipp_sel, &buf_len); csic_dma_flip_size(vinc->vipp_sel, &flip_size); csic_dma_flip_en(vinc->vipp_sel, &flip); - csic_dma_line_cnt(vinc->vipp_sel, cap->frame.o_height / 16 * 12); + /* give up line_cut interrupt. process in vsync and frame_done isr.*/ + /*csic_dma_line_cnt(vinc->vipp_sel, cap->frame.o_height / 16 * 12);*/ csic_frame_cnt_enable(vinc->vipp_sel); if (cap->frame.fmt.fourcc == V4L2_PIX_FMT_FBC) csic_fbc_enable(vinc->vipp_sel); else csic_dma_enable(vinc->vipp_sel); csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL); - csic_dma_int_enable(vinc->vipp_sel, DMA_INT_ALL); + if (vinc->isp_dbg.debug_en) + csic_dma_int_enable(vinc->vipp_sel, DMA_INT_ALL & ~(DMA_INT_FBC_OVHD_WRDDR_FULL)); + else + csic_dma_int_enable(vinc->vipp_sel, DMA_INT_ALL); + csic_dma_int_disable(vinc->vipp_sel, DMA_INT_LINE_CNT); } else { csic_dma_int_disable(vinc->vipp_sel, DMA_INT_ALL); csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL); diff --git a/drivers/media/platform/sunxi-vin/vin-vipp/sunxi_scaler.c b/drivers/media/platform/sunxi-vin/vin-vipp/sunxi_scaler.c index bc807df9..a86b8597 100644 --- a/drivers/media/platform/sunxi-vin/vin-vipp/sunxi_scaler.c +++ b/drivers/media/platform/sunxi-vin/vin-vipp/sunxi_scaler.c @@ -448,6 +448,8 @@ static int sunxi_scaler_subdev_s_stream(struct v4l2_subdev *sd, int enable) case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV61M: + case V4L2_PIX_FMT_NV16M: out_fmt = YUV422; break; default: @@ -536,34 +538,25 @@ int __scaler_init_subdev(struct scaler_dev *scaler) static int scaler_resource_alloc(struct scaler_dev *scaler) { int ret = 0; - scaler->vipp_reg.size = VIPP_REG_SIZE; - scaler->osd_para.size = OSD_PARA_SIZE; - scaler->osd_stat.size = OSD_STAT_SIZE; + scaler->vipp_reg.size = VIPP_REG_SIZE + OSD_PARA_SIZE + OSD_STAT_SIZE; ret = os_mem_alloc(&scaler->pdev->dev, &scaler->vipp_reg); if (ret < 0) { vin_err("scaler regs load addr requset failed!\n"); return -ENOMEM; } - ret = os_mem_alloc(&scaler->pdev->dev, &scaler->osd_para); - if (ret < 0) { - vin_err("scaler para load addr requset failed!\n"); - return -ENOMEM; - } - ret = os_mem_alloc(&scaler->pdev->dev, &scaler->osd_stat); - if (ret < 0) { - vin_err("scaler statistic load addr requset failed!\n"); - return -ENOMEM; - } - return 0; + scaler->osd_para.dma_addr = scaler->vipp_reg.dma_addr + VIPP_REG_SIZE; + scaler->osd_para.vir_addr = scaler->vipp_reg.vir_addr + VIPP_REG_SIZE; + scaler->osd_stat.dma_addr = scaler->osd_para.dma_addr + OSD_PARA_SIZE; + scaler->osd_stat.vir_addr = scaler->osd_para.vir_addr + OSD_PARA_SIZE; + + return 0; } static void scaler_resource_free(struct scaler_dev *scaler) { os_mem_free(&scaler->pdev->dev, &scaler->vipp_reg); - os_mem_free(&scaler->pdev->dev, &scaler->osd_para); - os_mem_free(&scaler->pdev->dev, &scaler->osd_stat); } static int scaler_probe(struct platform_device *pdev) diff --git a/drivers/media/platform/sunxi-vin/vin.c b/drivers/media/platform/sunxi-vin/vin.c index cdb3e96f..c7a11d90 100644 --- a/drivers/media/platform/sunxi-vin/vin.c +++ b/drivers/media/platform/sunxi-vin/vin.c @@ -58,6 +58,8 @@ char act_name[I2C_NAME_SIZE] = ""; uint act_slave = 0xff; uint use_sensor_list = 0xff; uint vin_i2c_dbg; +uint ptn_on_cnt; +extern uint ptn_frame_cnt; module_param_string(ccm, ccm, sizeof(ccm), S_IRUGO | S_IWUSR); module_param(i2c_addr, uint, S_IRUGO | S_IWUSR); @@ -482,8 +484,6 @@ static int vin_pipeline_s_power(struct vin_pipeline *p, bool on) unsigned int idx = seq[on][i]; if (!p->sd[idx] || !p->sd[idx]->entity.parent) continue; - if (vin_cap->vinc->ptn_cfg.ptn_en && (idx <= VIN_IND_MIPI)) - continue; mutex_lock(&p->sd[idx]->entity.parent->graph_mutex); ret = __vin_subdev_set_power(p->sd[idx], on); mutex_unlock(&p->sd[idx]->entity.parent->graph_mutex); @@ -496,8 +496,6 @@ static int vin_pipeline_s_power(struct vin_pipeline *p, bool on) unsigned int idx = seq[on][i]; if (!p->sd[idx] || !p->sd[idx]->entity.parent) continue; - if (vin_cap->vinc->ptn_cfg.ptn_en && (idx <= VIN_IND_MIPI)) - continue; mutex_lock(&p->sd[idx]->entity.parent->graph_mutex); __vin_subdev_set_power(p->sd[idx], !on); mutex_unlock(&p->sd[idx]->entity.parent->graph_mutex); @@ -640,8 +638,18 @@ static int __vin_pipeline_s_stream(struct vin_pipeline *p, int on_idx) } usleep_range(100, 120); } - if (vin_cap->vinc->ptn_cfg.ptn_en) - csic_ptn_generation_en(vind->id, on); + if (vin_cap->vinc->ptn_cfg.ptn_en) { + if (vin_cap->vinc->ptn_cfg.ptn_type > 0) { + ptn_on_cnt++; + if (ptn_on_cnt%vin_cap->vinc->ptn_cfg.ptn_type == 0) { + ptn_on_cnt = 0; + ptn_frame_cnt = 0; + csic_ptn_generation_en(vind->id, on); + } + } else { + csic_ptn_generation_en(vind->id, on); + } + } return 0; error: diff --git a/drivers/power/axp/axp-charger.c b/drivers/power/axp/axp-charger.c index 3d9ae056..74855276 100644 --- a/drivers/power/axp/axp-charger.c +++ b/drivers/power/axp/axp-charger.c @@ -641,6 +641,9 @@ static s32 axp_usb_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_PRESENT: case POWER_SUPPLY_PROP_ONLINE: + chg_dev->usb_pc_charging = (((CHARGE_USB_20 == axp_usbcurflag) + || (CHARGE_USB_30 == axp_usbcurflag)) + && (chg_dev->ext_valid)); val->intval = chg_dev->usb_pc_charging; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: diff --git a/drivers/power/axp/axp22x/axp22x-charger.c b/drivers/power/axp/axp22x/axp22x-charger.c index e565baaa..83e36735 100755 --- a/drivers/power/axp/axp22x/axp22x-charger.c +++ b/drivers/power/axp/axp22x/axp22x-charger.c @@ -360,6 +360,8 @@ static int axp22x_charger_init(struct axp_dev *axp_dev) struct axp_regmap *map = axp_dev->regmap; int i, update_min_times[8] = {30, 60, 120, 164, 0, 5, 10, 20}; + axp_regmap_read(map, AXP22X_CHARGE_CONTROL1, &val); + if (axp22x_config.pmu_init_chgend_rate == 10) val &= ~(1 << 4); else diff --git a/drivers/power/axp/axp22x/axp22x-regulator.c b/drivers/power/axp/axp22x/axp22x-regulator.c index 95a5f5da..27f9be1d 100755 --- a/drivers/power/axp/axp22x/axp22x-regulator.c +++ b/drivers/power/axp/axp22x/axp22x-regulator.c @@ -141,9 +141,9 @@ static struct axp_regulator_info axp22x_regulator_info[] = { AXP22X_LDO(11, 700, 3300, 100, LDO11, 0, 5, LDO11EN, 0x04, 0x04, 0x00, 0, 0, 0, 0, 0, 0, 0, 0), AXP22X_LDO(IO0, 700, 3300, 100, LDOIO0, 0, 5, LDOIO0EN, 0x07, 0x03, - 0x00, 0, 0, 0, 0, 0, 0, 0, 0), + 0x04, 0, 0, 0, 0, 0, 0, 0, 0), AXP22X_LDO(IO1, 700, 3300, 100, LDOIO1, 0, 5, LDOIO1EN, 0x07, 0x03, - 0x00, 0, 0, 0, 0, 0, 0, 0, 0), + 0x04, 0, 0, 0, 0, 0, 0, 0, 0), #ifdef CONFIG_AW_AXP233 AXP22X_SW(0, 3300, 3300, 100, SW0, 0, 0, SW0EN, 0x40, 0x40, 0x00, 0, 0, 0, 0, 0, 0, 0, 0), diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index 469612c9..24e66027 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c @@ -522,9 +522,21 @@ static int sunxi_rtc_probe(struct platform_device *pdev) */ tmp_data = readl(chip->base + SUNXI_LOSC_CTRL); tmp_data &= (~REG_CLK32K_AUTO_SWT_EN); + + /* Disable auto switch function */ + tmp_data |= REG_CLK32K_AUTO_SWT_BYPASS; + writel(tmp_data, chip->base + SUNXI_LOSC_CTRL); + + tmp_data = readl(chip->base + SUNXI_LOSC_CTRL); tmp_data |= (RTC_SOURCE_EXTERNAL | REG_LOSCCTRL_MAGIC); - tmp_data |= (EXT_LOSC_GSM); writel(tmp_data, chip->base + SUNXI_LOSC_CTRL); + + /* We need to set GSM after change clock source */ + udelay(60); + tmp_data = readl(chip->base + SUNXI_LOSC_CTRL); + tmp_data |= (EXT_LOSC_GSM | REG_LOSCCTRL_MAGIC); + writel(tmp_data, chip->base + SUNXI_LOSC_CTRL); + device_init_wakeup(&pdev->dev, 1); chip->rtc = devm_rtc_device_register(&pdev->dev, "sunxi-rtc", diff --git a/drivers/rtc/rtc-sunxi.h b/drivers/rtc/rtc-sunxi.h index 8d352bd0..bdb67ade 100644 --- a/drivers/rtc/rtc-sunxi.h +++ b/drivers/rtc/rtc-sunxi.h @@ -18,6 +18,7 @@ #define SUNXI_LOSC_CTRL_RTC_YMD_ACC BIT(7) #define REG_LOSCCTRL_MAGIC 0x16aa0000 #define REG_CLK32K_AUTO_SWT_EN BIT(14) +#define REG_CLK32K_AUTO_SWT_BYPASS BIT(15) #define RTC_SOURCE_EXTERNAL 0x00000001 #define EXT_LOSC_GSM 0x00000008 #define SUNXI_ALARM_CONFIG 0x0050 diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c index 8f654d9c..111afd75 100644 --- a/drivers/spi/spi-sunxi.c +++ b/drivers/spi/spi-sunxi.c @@ -2036,7 +2036,7 @@ static void __exit sunxi_spi_exit(void) platform_driver_unregister(&sunxi_spi_driver); } -module_init(sunxi_spi_init); +device_paralell_initcall(sunxi_spi_init); module_exit(sunxi_spi_exit); MODULE_AUTHOR("pannan"); diff --git a/drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c b/drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c index d8ae16e1..b75c2ace 100644 --- a/drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c +++ b/drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c @@ -2504,7 +2504,7 @@ static void __exit disp_module_exit(void) cdev_del(my_cdev); } -module_init(disp_module_init); +device_paralell_initcall(disp_module_init); module_exit(disp_module_exit); MODULE_AUTHOR("tan"); diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 1cb70a0b..0137d5eb 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -191,6 +191,17 @@ void squashfs_cache_put(struct squashfs_cache_entry *entry) entry->refcount--; if (entry->refcount == 0) { cache->unused++; + + /* + * If error of this entry is occured, we need to + * mark it to SQUASHFS_INVALID_BLK, and clear the + * error variable. + */ + if(entry->error) { + entry->error = 0; + entry->block = SQUASHFS_INVALID_BLK; + } + /* * If there's any processes waiting for a block to become * available, wake one up. diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index a65eedc1..57ba1494 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -681,6 +681,7 @@ INIT_CALLS_LEVEL(rootfs) \ INIT_CALLS_LEVEL(6) \ INIT_CALLS_LEVEL(7) \ + INIT_CALLS_LEVEL(8) \ VMLINUX_SYMBOL(__initcall_end) = .; #define CON_INITCALL \ diff --git a/include/linux/device.h b/include/linux/device.h index b8f411b5..a81e63f7 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1333,6 +1333,24 @@ static void __exit __driver##_exit(void) \ } \ module_exit(__driver##_exit); + +/* module_driver_paralell() - The distinction between this + * and module_driver() is the module's init_func will be setup + * in a way of paralell. + */ +#define module_driver_paralell(__driver, __register, __unregister, ...) \ +static int __init __driver##_init(void) \ +{ \ + return __register(&(__driver), ##__VA_ARGS__); \ +} \ +device_paralell_initcall(__driver##_init); \ +static void __exit __driver##_exit(void) \ +{ \ + __unregister(&(__driver), ##__VA_ARGS__); \ +} \ +module_exit(__driver##_exit); + + /** * builtin_driver() - Helper macro for drivers that don't do anything * special in init and have no exit. This eliminates some boilerplate. diff --git a/include/linux/init.h b/include/linux/init.h index aedb254a..2d4ad221 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -215,10 +215,11 @@ extern bool initcall_debug; #define fs_initcall(fn) __define_initcall(fn, 5) #define fs_initcall_sync(fn) __define_initcall(fn, 5s) #define rootfs_initcall(fn) __define_initcall(fn, rootfs) -#define device_initcall(fn) __define_initcall(fn, 6) -#define device_initcall_sync(fn) __define_initcall(fn, 6s) -#define late_initcall(fn) __define_initcall(fn, 7) -#define late_initcall_sync(fn) __define_initcall(fn, 7s) +#define device_paralell_initcall(fn) __define_initcall(fn, 6) +#define device_initcall(fn) __define_initcall(fn, 7) +#define device_initcall_sync(fn) __define_initcall(fn, 7s) +#define late_initcall(fn) __define_initcall(fn, 8) +#define late_initcall_sync(fn) __define_initcall(fn, 8s) #define __initcall(fn) device_initcall(fn) diff --git a/include/linux/platform_data/invensense_mpu6050.h b/include/linux/platform_data/invensense_mpu6050.h index ad3aa7b9..6ba02abb 100644 --- a/include/linux/platform_data/invensense_mpu6050.h +++ b/include/linux/platform_data/invensense_mpu6050.h @@ -26,6 +26,7 @@ */ struct inv_mpu6050_platform_data { __s8 orientation[9]; + int int_gpio; }; #endif diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index dc777be5..e8b2b6c2 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -222,6 +222,13 @@ static inline void platform_set_drvdata(struct platform_device *pdev, module_driver(__platform_driver, platform_driver_register, \ platform_driver_unregister) +/* module_platform_driver_paralell() - The distinction between this + * and module_platform_driver() is the module's init_func will be setup + * in a way of paralell. + */ +#define module_platform_driver_paralell(__platform_driver) \ + module_driver_paralell(__platform_driver, platform_driver_register, \ + platform_driver_unregister) /* builtin_platform_driver() - Helper macro for builtin drivers that * don't do anything special in driver init. This eliminates some * boilerplate. Each driver may only use this macro once, and diff --git a/include/media/sunxi_camera_v2.h b/include/media/sunxi_camera_v2.h index 91eb8b9c..308490ad 100644 --- a/include/media/sunxi_camera_v2.h +++ b/include/media/sunxi_camera_v2.h @@ -204,6 +204,9 @@ struct vin_pattern_config { __u32 ptn_type; }; +struct vin_reset_time { + __u32 reset_time; +}; #define VIDIOC_ISP_AE_STAT_REQ \ _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct isp_stat_buf) @@ -227,6 +230,8 @@ struct vin_pattern_config { _IOWR('V', BASE_VIDIOC_PRIVATE + 10, struct isp_debug_mode) #define VIDIOC_VIN_PTN_CFG \ _IOWR('V', BASE_VIDIOC_PRIVATE + 11, struct vin_pattern_config) +#define VIDIOC_VIN_RESET_TIME \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct vin_reset_time) /* * Events diff --git a/init/initramfs.c b/init/initramfs.c index f8ce812b..24199799 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -672,4 +672,4 @@ static int __init populate_rootfs(void) } return 0; } -rootfs_initcall(populate_rootfs); +device_paralell_initcall(populate_rootfs); diff --git a/init/main.c b/init/main.c index 9383e542..030b8162 100644 --- a/init/main.c +++ b/init/main.c @@ -816,6 +816,7 @@ extern initcall_t __initcall4_start[]; extern initcall_t __initcall5_start[]; extern initcall_t __initcall6_start[]; extern initcall_t __initcall7_start[]; +extern initcall_t __initcall8_start[]; extern initcall_t __initcall_end[]; static initcall_t *initcall_levels[] __initdata = { @@ -827,6 +828,7 @@ static initcall_t *initcall_levels[] __initdata = { __initcall5_start, __initcall6_start, __initcall7_start, + __initcall8_start, __initcall_end, }; @@ -838,10 +840,80 @@ static char *initcall_level_names[] __initdata = { "arch", "subsys", "fs", + "device_paralell", "device", "late", }; +#define CONFIG_INTTCALL_PARALLEL +#ifdef CONFIG_INTTCALL_PARALLEL +struct completion initcall_paralell_comp; +static atomic_t thread_end_count = ATOMIC_INIT(0); +#define PARALELL_INITCALL_LEVEL 6 +static int __ref initcall_paralell_thread(void *param) +{ + initcall_t fn; + /*cpumask_var_t shuffle_tmp_mask; + cpumask_setall(shuffle_tmp_mask); + set_cpus_allowed_ptr(current, shuffle_tmp_mask);*/ + + fn = (initcall_t)param; + + /*sprintf(fn_name, "%pF", fn); + if (0 == strncmp("populate_rootfs",fn_name, strlen("populate_rootfs"))) { + if (sched_setaffinity(current->pid, cpumask_of(1)) != 0) { + printk(KERN_EMERG"sched_setaffinity is failed\n"); + } + } + pr_info("Initcall_thread: %pF pid : %d, cpus_allowed: %d, thread_info:%d, %d\n", \ + fn, current->pid, current->cpus_allowed, current_thread_info()->cpu,smp_processor_id());*/ + + do_one_initcall(fn); + + if (atomic_dec_and_test(&thread_end_count)) { + pr_info("%pF complete comp.\n", fn); + complete(&(initcall_paralell_comp)); + } + + return 0; +} + +static void __init wait_for_parallel_initcall(void) +{ + wait_for_completion(&(initcall_paralell_comp)); +} + +static int __init do_initcall_level(int level, bool parallel_level) +{ + initcall_t *fn; + char *thread_name; + static int initcall_count; + int initcall_paralell_devices = 0; + + strcpy(initcall_command_line, saved_command_line); + parse_args(initcall_level_names[level], + initcall_command_line, __start___param, + __stop___param - __start___param, + level, level, + NULL, &repair_env_string); + + if (true == parallel_level) { + for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) { + ++initcall_paralell_devices; + if (initcall_paralell_devices == 1) + init_completion(&(initcall_paralell_comp)); + thread_name = kasprintf(GFP_KERNEL, "%pf%d", fn, initcall_count++); + atomic_add(1, &thread_end_count); + kthread_run(initcall_paralell_thread, *fn, thread_name); + } + } else { + for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) { + do_one_initcall(*fn); + } + } + return initcall_paralell_devices; +} +#else static void __init do_initcall_level(int level) { initcall_t *fn; @@ -853,16 +925,31 @@ static void __init do_initcall_level(int level) level, level, NULL, &repair_env_string); - for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) - do_one_initcall(*fn); + for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) { + do_one_initcall(*fn); + } } +#endif static void __init do_initcalls(void) { - int level; - + int level, initcall_paralell_devices = 0; +#ifdef CONFIG_INTTCALL_PARALLEL + for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { + if (level == PARALELL_INITCALL_LEVEL) { + initcall_paralell_devices = do_initcall_level(level, true); + } else if (level == PARALELL_INITCALL_LEVEL + 1) { + do_initcall_level(level, false); + if (initcall_paralell_devices > 0) + wait_for_parallel_initcall(); + } else { + do_initcall_level(level, false); + } + } +#else for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) do_initcall_level(level); +#endif } /* diff --git a/kernel/fork.c b/kernel/fork.c index c85efa77..0bee855b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -104,7 +104,7 @@ unsigned long total_forks; /* Handle normal Linux uptimes. */ int nr_threads; /* The idle threads do not count.. */ -int max_threads; /* tunable limit on nr_threads */ +int max_threads __read_mostly; /* tunable limit on nr_threads */ DEFINE_PER_CPU(unsigned long, process_counts) = 0; diff --git a/sound/soc/sunxi/sunxi-dmic.c b/sound/soc/sunxi/sunxi-dmic.c index e5ef0b63..c4edb67f 100644 --- a/sound/soc/sunxi/sunxi-dmic.c +++ b/sound/soc/sunxi/sunxi-dmic.c @@ -79,6 +79,103 @@ static const struct dmic_rate dmic_rate_s[] = { {8000, 0x5}, }; +static struct label reg_labels[] = { + LABEL(SUNXI_DMIC_EN), + LABEL(SUNXI_DMIC_SR), + LABEL(SUNXI_DMIC_CTR), + LABEL(SUNXI_DMIC_INTC), + LABEL(SUNXI_DMIC_INTS), + LABEL(SUNXI_DMIC_FIFO_CTR), + LABEL(SUNXI_DMIC_FIFO_STA), + LABEL(SUNXI_DMIC_CH_NUM), + LABEL(SUNXI_DMIC_CH_MAP), + LABEL(SUNXI_DMIC_CNT), + LABEL(SUNXI_DMIC_DATA0_1_VOL), + LABEL(SUNXI_DMIC_DATA2_3_VOL), + LABEL(SUNXI_DMIC_HPF_CTRL), + LABEL(SUNXI_DMIC_HPF_COEF), + LABEL(SUNXI_DMIC_HPF_GAIN), + LABEL_END, +}; + +static void __iomem *sunxi_dmic_membase; + +/* + * ex: + * param 1: 0 read;1 write + * param 2: address; + * param 3: write value; + * read: + * echo 0,0x00 > dmic_reg_debug + * echo 0,0x04 > dmic_reg_debug + * write: + * echo 1,0x00,0xa > dmic_reg_debug + * echo 1,0x00,0xff > dmic_reg_debug + */ +static ssize_t dmic_class_debug_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + int ret; + int rw_flag; + int reg_val_read; + int input_reg_val = 0; + int input_reg_offset = 0; + + ret = sscanf(buf, "%d,0x%x,0x%x", &rw_flag, &input_reg_offset, + &input_reg_val); + + if (!(rw_flag == 1 || rw_flag == 0)) { + pr_err("not rw_flag\n"); + return count; + } + if (ret == 3 || ret == 2) { + if (rw_flag) { + writel(input_reg_val, + sunxi_dmic_membase + input_reg_offset); + } + reg_val_read = readl(sunxi_dmic_membase + input_reg_offset); + pr_err("\n\n Reg[0x%x] : 0x%x\n\n", + input_reg_offset, reg_val_read); + } else { + pr_err("ret:%d, The num of params invalid!\n", ret); + pr_err("\nExample:\n"); + pr_err("\nRead reg[0x04]:\n"); + pr_err(" echo 0,0x04 > dmic_reg_debug\n"); + pr_err("Write reg[0x04]=0x10\n"); + pr_err(" echo 1,0x04,0x10 > dmic_reg_debug\n"); + } + + return count; +} + +static ssize_t dmic_class_debug_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int count = 0; + int i = 0; + + count += sprintf(buf, "Dump dmic reg:\n"); + + while (reg_labels[i].name != NULL) { + count += sprintf(buf + count, "%s 0x%p: 0x%x\n", + reg_labels[i].name, + (sunxi_dmic_membase + reg_labels[i].address), + readl(sunxi_dmic_membase + reg_labels[i].address)); + i++; + } + + return count; +} + +static struct class_attribute dmic_class_attrs[] = { + __ATTR(dmic_reg_debug, S_IRUGO|S_IWUSR, dmic_class_debug_show, dmic_class_debug_store), + __ATTR_NULL +}; +static struct class dmic_class = { + .name = "dmic", + .class_attrs = dmic_class_attrs, +}; + /* * Configure DMA , Chan enable & Global enable */ @@ -121,6 +218,8 @@ static int sunxi_dmic_hw_params(struct snd_pcm_substream *substream, struct sunxi_dmic_info *sunxi_dmic = snd_soc_dai_get_drvdata(dai); int i; + sunxi_dmic_init(sunxi_dmic); + /* sample resolution & sample fifo format */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -197,16 +296,14 @@ static int sunxi_dmic_prepare(struct snd_pcm_substream *substream, { struct sunxi_dmic_info *sunxi_dmic = snd_soc_dai_get_drvdata(dai); + regmap_update_bits(sunxi_dmic->regmap, SUNXI_DMIC_FIFO_CTR, + (0x1 << DMIC_FIFO_FLUSH), (0x1 << DMIC_FIFO_FLUSH)); + regmap_write(sunxi_dmic->regmap, SUNXI_DMIC_INTS, - (1<regmap, SUNXI_DMIC_CNT, 0x0); - regmap_write(sunxi_dmic->regmap, SUNXI_DMIC_FIFO_STA, 0x0); - - regmap_update_bits(sunxi_dmic->regmap, SUNXI_DMIC_FIFO_CTR, - (1<moduleclk) + clk_disable(sunxi_dmic->moduleclk); +} + static int sunxi_dmic_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { @@ -231,6 +338,10 @@ static int sunxi_dmic_set_sysclk(struct snd_soc_dai *dai, int clk_id, return -EINVAL; } + /* IC: Gating and Reset must be set here */ + if (sunxi_dmic->moduleclk) + clk_prepare_enable(sunxi_dmic->moduleclk); + return 0; } @@ -261,8 +372,10 @@ static int sunxi_dmic_suspend(struct snd_soc_dai *cpu_dai) sunxi_dmic->pinctrl = NULL; sunxi_dmic->pinstate = NULL; sunxi_dmic->pinstate_sleep = NULL; +#if 0 if (sunxi_dmic->moduleclk != NULL) clk_disable(sunxi_dmic->moduleclk); +#endif if (sunxi_dmic->pllclk != NULL) clk_disable(sunxi_dmic->pllclk); @@ -281,13 +394,13 @@ static int sunxi_dmic_resume(struct snd_soc_dai *cpu_dai) pr_err("open sunxi_dmic->pllclk failed! line = %d\n", __LINE__); } } - +#if 0 if (sunxi_dmic->moduleclk != NULL) { if (clk_prepare_enable(sunxi_dmic->moduleclk)) { pr_err("open sunxi_dmic->moduleclk failed! line = %d\n", __LINE__); } } - +#endif if (!sunxi_dmic->pinctrl) { sunxi_dmic->pinctrl = devm_pinctrl_get(cpu_dai->dev); if (IS_ERR_OR_NULL(sunxi_dmic->pinctrl)) { @@ -316,8 +429,9 @@ static int sunxi_dmic_resume(struct snd_soc_dai *cpu_dai) pr_warn("[dmic]select pin default state failed\n"); return ret; } - +#if 0 sunxi_dmic_init(sunxi_dmic); +#endif pr_debug("[DMIC]End %s\n", __func__); return 0; } @@ -329,6 +443,7 @@ static struct snd_soc_dai_ops sunxi_dmic_dai_ops = { .prepare = sunxi_dmic_prepare, .hw_params = sunxi_dmic_hw_params, .set_sysclk = sunxi_dmic_set_sysclk, + .shutdown = sunxi_dmic_shutdown, }; static struct snd_soc_dai_driver sunxi_dmic_dai = { @@ -361,7 +476,6 @@ static int sunxi_dmic_dev_probe(struct platform_device *pdev) struct resource res, *memregion; struct device_node *np = pdev->dev.of_node; struct sunxi_dmic_info *sunxi_dmic; - void __iomem *sunxi_dmic_membase = NULL; int ret; sunxi_dmic = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_dmic_info), GFP_KERNEL); @@ -427,38 +541,13 @@ static int sunxi_dmic_dev_probe(struct platform_device *pdev) goto err_iounmap; } - sunxi_dmic->pllclk = of_clk_get(np, 0); - sunxi_dmic->moduleclk = of_clk_get(np, 1); - if (IS_ERR(sunxi_dmic->pllclk) || IS_ERR(sunxi_dmic->moduleclk)) { - dev_err(&pdev->dev, "Can't get dmic pll clocks\n"); - if (IS_ERR(sunxi_dmic->pllclk)) { - ret = PTR_ERR(sunxi_dmic->pllclk); - goto err_iounmap; - } else { - ret = PTR_ERR(sunxi_dmic->moduleclk); - goto err_pllclk_put; - } - } else { - if (clk_set_parent(sunxi_dmic->moduleclk, sunxi_dmic->pllclk)) { - pr_err("try to set parent failed! line = %d\n", __LINE__); - } - clk_prepare_enable(sunxi_dmic->pllclk); - clk_prepare_enable(sunxi_dmic->moduleclk); - } - - /* FIXME */ - sunxi_dmic->capture_dma_param.dma_addr = res.start + SUNXI_DMIC_DATA; - sunxi_dmic->capture_dma_param.dma_drq_type_num = DRQSRC_DMIC; - sunxi_dmic->capture_dma_param.src_maxburst = 8; - sunxi_dmic->capture_dma_param.dst_maxburst = 8; - sunxi_dmic->pinctrl = NULL; if (!sunxi_dmic->pinctrl) { sunxi_dmic->pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR_OR_NULL(sunxi_dmic->pinctrl)) { dev_err(&pdev->dev, "request pinctrl handle for audio failed\n"); ret = -EINVAL; - goto err_moduleclk_put; + goto err_iounmap; } } if (!sunxi_dmic->pinstate) { @@ -484,12 +573,42 @@ static int sunxi_dmic_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "pin select state failed\n"); goto err_pinctrl_put; } + + sunxi_dmic->pllclk = of_clk_get(np, 0); + sunxi_dmic->moduleclk = of_clk_get(np, 1); + if (IS_ERR(sunxi_dmic->pllclk) || IS_ERR(sunxi_dmic->moduleclk)) { + dev_err(&pdev->dev, "Can't get dmic pll clocks\n"); + if (IS_ERR(sunxi_dmic->pllclk)) { + ret = PTR_ERR(sunxi_dmic->pllclk); + goto err_pinctrl_put; + } else { + ret = PTR_ERR(sunxi_dmic->moduleclk); + goto err_pllclk_put; + } + } else { + if (clk_set_parent(sunxi_dmic->moduleclk, sunxi_dmic->pllclk)) { + pr_err("try to set parent failed! line = %d\n", __LINE__); + } + clk_prepare_enable(sunxi_dmic->pllclk); + /* + * The moduleclk should enable at startup + * and disable at shutdown + */ + /*clk_prepare_enable(sunxi_dmic->moduleclk);*/ + } + + /* FIXME */ + sunxi_dmic->capture_dma_param.dma_addr = res.start + SUNXI_DMIC_DATA; + sunxi_dmic->capture_dma_param.dma_drq_type_num = DRQSRC_DMIC; + sunxi_dmic->capture_dma_param.src_maxburst = 8; + sunxi_dmic->capture_dma_param.dst_maxburst = 8; + ret = snd_soc_register_component(&pdev->dev, &sunxi_dmic_component, &sunxi_dmic->dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; - goto err_pinctrl_put; + goto err_pllclk_put; } ret = asoc_dma_platform_register(&pdev->dev, 0); @@ -499,16 +618,22 @@ static int sunxi_dmic_dev_probe(struct platform_device *pdev) goto err_unregister_component; } + ret = class_register(&dmic_class); + if (ret) + pr_warn("daudio: Failed to create debugfs directory\n"); + return 0; err_unregister_component: snd_soc_unregister_component(&pdev->dev); -err_pinctrl_put: - devm_pinctrl_put(sunxi_dmic->pinctrl); +#if 0 err_moduleclk_put: clk_put(sunxi_dmic->moduleclk); +#endif err_pllclk_put: clk_put(sunxi_dmic->pllclk); +err_pinctrl_put: + devm_pinctrl_put(sunxi_dmic->pinctrl); err_iounmap: iounmap(sunxi_dmic_membase); err_regulator_put: diff --git a/sound/soc/sunxi/sunxi-dmic.h b/sound/soc/sunxi/sunxi-dmic.h index 3869fe30..43b8ee64 100644 --- a/sound/soc/sunxi/sunxi-dmic.h +++ b/sound/soc/sunxi/sunxi-dmic.h @@ -108,4 +108,19 @@ #define DATA2R_VOL 0 #define DMIC_DEFAULT_VOL 0xB0B0B0B0 +struct label { + const char *name; + const unsigned int address; + int value; +}; + +#define LABEL(constant) \ + { \ + #constant, constant, 0 \ + } +#define LABEL_END \ + { \ + NULL, -1, 0 \ + } + #endif /* SUNXI_DMIC_H */