| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963 |
- /*
- * ark7116h - Arkmicro ark7116h video decoder driver
- *
- * Copyright (c) 2020,2021 Arkmicro, Inc.
- * This code is placed under the terms of the GNU General Public License v2
- */
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/interrupt.h>
- #include <linux/i2c.h>
- #include <linux/slab.h>
- #include <linux/of.h>
- #include <linux/gpio/consumer.h>
- #include <linux/videodev2.h>
- #include <media/v4l2-ioctl.h>
- #include <media/v4l2-event.h>
- #include <media/v4l2-device.h>
- #include <media/v4l2-ctrls.h>
- #include <linux/mutex.h>
- #include <linux/delay.h>
- //#define ARK7116H_DUMP_REGS
- #define ARK7116H_STATUS 0xFD26
- #define ARK7116H_INPUT_CTL 0xFDD4
- #define ARK7116H_CONTRAST_CTL 0xFE53
- #define ARK7116H_BRIGHT_CTL 0xFE54
- #define ARK7116H_HUE_CTL 0xFE55
- #define ARK7116H_SATURATION_CTL 0xFE56
- #define ARK7116H_AV0 0
- #define ARK7116H_AV1 1
- #define ARK7116H_AV2 2
- typedef enum {
- DISP_16_9 = 0,
- DISP_4_3,
- }ConfigDisplayMode;
- enum {
- TYPE_UNKNOWN = -1,
- TYPE_CVBS = 0,
- TYPE_720P,
- TYPE_1080P,
- };
- enum {
- TYPE_UNDEF = -1,
- TYPE_ARK7116 = 0,
- TYPE_ARK7116H,
- TYPE_RN6752,
- TYPE_PR2000,
- };
- typedef struct {
- unsigned int addr;
- unsigned char value;
- } PanlstaticPara;
- typedef struct {
- unsigned int addr;
- unsigned char value[6];
- }PanlPosDynPara;
- PanlstaticPara AV1_staticPara[]=
- {
- //GLOBAL
- {0XFB01,0X01},
- {0XFB02,0X40},
- {0XFB03,0X16},
- {0XFB04,0X00},
- {0XFB05,0X00},
- {0XFB06,0XC0},
- {0XFB07,0X00},
- {0XFB08,0X04},
- {0XFB09,0X04},
- {0XFB0A,0X5C},
- {0XFB0B,0XFF},
- {0XFB0C,0XF2},
- {0XFB0D,0XAA},
- {0XFB0E,0XAA},
- {0XFB0F,0X2A},
- {0XFB10,0X01},
- {0XFB11,0X02},
- {0XFB12,0X02},
- {0XFB13,0X28},
- {0XFB14,0X7F},
- {0XFB15,0X00},
- {0XFB16,0X07},
- {0XFB17,0X0C},
- {0XFB18,0X0C},
- {0XFB19,0X00},
- {0XFB1A,0X00},
- {0XFB1B,0X0C},
- {0XFB1C,0X0C},
- {0XFB1D,0X13},
- {0XFB1E,0X2B},
- {0XFB1F,0X12},
- {0XFB20,0X80},
- {0XFB21,0X00},
- {0XFB22,0X00},
- {0XFB23,0X2A},
- {0XFB24,0X11},
- {0XFB25,0XE8},
- {0XFB26,0X03},
- {0XFB27,0XFF},
- {0XFB28,0X0C},
- {0XFB29,0X95},
- {0XFB2A,0X55},
- {0XFB2B,0X55},
- {0XFB2C,0XC0},
- {0XFB2D,0X00},
- {0XFB2E,0X55},
- {0XFB2F,0X55},
- {0XFB30,0X55},
- {0XFB31,0X55},
- {0XFB32,0X55},
- {0XFB33,0XCC},
- {0XFB34,0X1A},
- {0XFB35,0X00},
- {0XFB36,0X04},
- {0XFB45,0XFF},
- {0XFB43,0X60},
- {0XFB37,0X8C},
- {0XFB38,0X10},
- {0XFB3D,0X8C},
- {0XFB41,0X28},
- {0XFB42,0X20},
- {0XFB44,0X04},
- {0XFB39,0X01},
- {0XFB3A,0X01},
- {0XFB3B,0X00},
- {0XFB3C,0X20},
- {0XFB3E,0X4C},
- {0XFB3F,0X20},
- {0XFB40,0X20},
- //DECODER
- {0XFD01,0X04},
- {0XFD02,0X00},
- {0XFD03,0X80},
- {0XFD04,0X80},
- {0XFD05,0X30},
- {0XFD06,0X02},
- {0XFD07,0X80},
- {0XFD08,0X00},
- {0XFD09,0X00},
- {0XFD0A,0X2F},
- {0XFD0B,0X40},
- {0XFD0C,0X12},
- {0XFD0D,0X03},
- {0XFD0E,0X72},
- {0XFD0F,0X07},
- {0XFD10,0X14},
- {0XFD11,0X09},
- {0XFD12,0X00},
- {0XFD13,0X1E},
- {0XFD14,0X22},
- {0XFD15,0X05},
- {0XFD26,0X0E},
- {0XFD27,0X00},
- {0XFD28,0X00},
- {0XFD2A,0X01},
- {0XFD35,0XAA},
- {0XFD36,0XAA},
- {0XFD37,0X60},
- {0XFD38,0X0F},
- {0XFD39,0X08},
- {0XFD48,0X07},
- {0XFD54,0X40},
- {0XFD55,0X8A},
- {0XFD5F,0XC0},
- {0XFD60,0X03},
- {0XFD61,0X2D},
- {0XFD62,0X41},
- {0XFD63,0XC0},
- {0XFD83,0X4F},
- {0XFDA0,0X0E},
- {0XFDAA,0X03},
- {0XFDAB,0X15},
- {0XFDAC,0X74},
- {0XFDB1,0X02},
- {0XFDB2,0X76},
- {0XFDB5,0X6F},
- {0XFDCA,0X4F},
- {0XFDCD,0X32},
- {0XFDD0,0X01},
- {0XFDD1,0X19},
- {0XFDD2,0X00},
- {0XFDD3,0X00},
- {0XFDD4,0X00},
- {0XFDD5,0XB1},
- {0XFDD6,0X08},
- {0XFDD7,0XF7},
- {0XFDD8,0XA3},
- {0XFDD9,0X40},
- {0XFDDA,0X29},
- {0XFDDB,0X00},
- {0XFDDC,0X00},
- {0XFDDD,0X4C},
- {0XFDDE,0X59},
- {0XFDDF,0X53},
- {0XFDE0,0X2E},
- {0XFDE1,0X17},
- {0XFDE2,0X00},
- {0XFD4F,0X40},
- {0XFD4F,0X40},
- {0XFD50,0X42},
- {0XFD31,0X20},
- {0XFD52,0X70},
- {0XFD4E,0X82},
- {0XFD7B,0XE5},
- {0XFD51,0X90},
- {0XFD16,0X4E},
- {0XFD98,0X0A},
- {0XFD1B,0X22},
- {0XFD1C,0X61},
- {0XFD41,0X8A},
- {0XFDCB,0X10},
- {0XFD43,0X80},
- {0XFD44,0X20},
- {0XFD45,0X80},
- {0XFD46,0X00},
- {0XFD56,0X07},
- {0XFD5D,0X03},
- {0XFD19,0X82},
- {0XFD1A,0X50},
- {0XFD1D,0X70},
- {0XFD8A,0X0A},
- {0XFD8B,0X00},
- {0XFDC8,0X00},
- {0XFDC9,0X01},
- {0XFDC6,0X00},
- {0XFD80,0X50},
- {0XFD7C,0X0A},
- {0XFD7D,0XFA},
- {0XFDB4,0XD2},
- //deinterlace
- {0XFE00,0X10},
- {0XFE01,0X00},
- {0XFE02,0X42},
- {0XFE03,0X0D},
- {0XFE04,0X30},
- {0XFE05,0X70},
- {0XFE06,0X00},
- {0XFE07,0X30},
- {0XFE08,0X02},
- {0XFE09,0X0B},
- {0XFE0A,0X02},
- {0XFE0B,0X00},
- {0XFE0C,0X40},
- {0XFE0D,0X00},
- {0XFE0E,0X08},
- {0XFE0F,0X00},
- {0XFE10,0X00},
- {0XFE11,0X00},
- {0XFE12,0XA0},
- {0XFE13,0XA0},
- {0XFE14,0X10},
- {0XFE15,0XA0},
- {0XFE16,0X20},
- {0XFE17,0X90},
- {0XFE18,0XA0},
- {0XFE19,0X60},
- {0XFE1A,0X40},
- {0XFE1B,0X04},
- {0XFE1C,0X04},
- {0XFE1D,0X00},
- {0XFE1E,0X10},
- {0XFE1F,0X22},
- {0XFEE0,0X30},
- {0XFEE1,0X00},
- {0XFEE2,0X36},
- {0XFE20,0XFF},
- {0XFE21,0XFF},
- {0XFE22,0XFF},
- {0XFE23,0XFF},
- {0XFE24,0XFF},
- {0XFE25,0XFF},
- {0XFE26,0XFF},
- //VP
- {0XFE30,0X27},
- {0XFE31,0X8F},
- {0XFE32,0X10},
- {0XFE33,0X10},
- {0XFE34,0X10},
- {0XFE35,0X60},
- {0XFE36,0X10},
- {0XFE37,0XD0},
- {0XFE38,0X10},
- {0XFE39,0X41},
- {0XFE3A,0X20},
- {0XFE3B,0X16},
- {0XFE3C,0X20},
- {0XFE3D,0X20},
- {0XFE3E,0X20},
- {0XFE3F,0X20},
- {0XFE40,0X64},
- {0XFE41,0X49},
- {0XFE42,0XFF},
- {0XFE43,0XFF},
- {0XFE44,0XFF},
- {0XFE45,0XFF},
- {0XFE46,0XFF},
- {0XFE47,0X4C},
- {0XFE48,0X1A},
- {0XFE49,0X15},
- {0XFE4A,0X55},
- {0XFE4B,0X80},
- {0XFE4C,0X80},
- {0XFE4D,0X00},
- {0XFE4E,0X00},
- {0XFE4F,0X80},
- {0XFE50,0X80},
- {0XFE51,0X0A},
- {0XFE52,0X4F},
- {0XFE53,0X80},
- {0XFE54,0X7A},
- {0XFE55,0X00},
- {0XFE56,0X38},
- {0XFE57,0X10},
- {0XFE58,0X80},
- {0XFE59,0X65},
- {0XFE5A,0X00},
- {0XFE5D,0XFF},
- {0XFE5E,0XFF},
- {0XFE5F,0XFF},
- {0XFE60,0X3C},
- {0XFE61,0XFF},
- {0XFE62,0XFF},
- {0XFE63,0XFF},
- {0XFE64,0XFF},
- {0XFE65,0XFF},
- {0XFE66,0XFF},
- {0XFE67,0X24},
- {0XFE68,0XFF},
- {0XFE69,0X20},
- {0XFE6A,0X9F},
- {0XFE70,0X42},
- {0XFE71,0XE0},
- {0XFE72,0XDE},
- {0XFE73,0XE1},
- {0XFE74,0XFD},
- {0XFE75,0X2E},
- {0XFE76,0XF0},
- {0XFE77,0XDD},
- {0XFE78,0XF0},
- {0XFE79,0XFD},
- {0XFE7A,0X33},
- {0XFE7B,0X81},
- //vi_regfile
- {0XFF01,0XFF},
- {0XFF02,0XFF},
- {0XFF03,0XFF},
- {0XFF04,0XFF},
- {0XFF05,0XFF},
- {0XFF06,0XFF},
- {0XFF07,0XFF},
- {0XFF08,0XFF},
- {0XFF09,0XFF},
- {0XFF0A,0XFF},
- {0XFF0B,0XFF},
- {0XFF0C,0XFF},
- {0XFF0D,0XFF},
- {0XFF0E,0XFF},
- {0XFF0F,0XFF},
- {0XFF10,0XFF},
- {0XFF11,0XFF},
- {0XFF12,0XFF},
- {0XFF13,0XFF},
- {0XFF14,0XFF},
- {0XFF15,0XFF},
- {0XFF16,0XFF},
- {0XFF17,0XFF},
- {0XFF18,0XFF},
- {0XFF19,0XFF},
- {0XFF1A,0XFF},
- {0XFF1B,0XFF},
- {0XFF1C,0XFF},
- {0XFF1D,0XFF},
- {0XFF1E,0XFF},
- {0XFF1F,0XFF},
- //scale
- {0XFF20,0XC0},
- {0XFF21,0X03},
- {0XFF22,0XA0}, //B6 ok //debug scale
- {0XFF23,0X03},
- {0XFF24,0XEE},
- {0XFF25,0X03},
- {0XFF26,0X07},
- {0XFF27,0X91},
- {0XFF28,0X51},
- {0XFF29,0X00},
- {0XFF2A,0X03},
- {0XFF2B,0X80},
- {0XFF2C,0X02},
- {0XFF2D,0XD0},
- {0XFF2E,0X02},
- {0XFF2F,0X40},
- {0XFF30,0X02},
- {0XFF31,0X02},
- {0XFF32,0X00},
- {0XFF33,0X28},
- {0XFF34,0X02},
- {0XFF35,0X00},
- {0XFF36,0X05},
- {0XFF37,0X11},
- {0XFF38,0X00},
- {0XFF39,0X27},
- {0XFF3A,0X03},
- {0XFF3B,0X00},
- {0XFF3C,0X00},
- {0XFF3D,0X37},
- {0XFF3E,0X02},
- {0XFF3F,0X00},
- {0XFF40,0X00},
- {0XFF41,0X00},
- {0XFF42,0X00},
- {0XFF43,0X00},
- {0XFF44,0X96},
- {0XFF45,0X00},
- {0XFF46,0X00},
- {0XFF47,0X00},
- {0XFF48,0X00},
- {0XFF49,0X19},
- {0XFF4A,0X00},
- {0XFF4B,0XE9},
- {0XFF4C,0X02},
- {0XFF4D,0X09},
- {0XFF4E,0X00},
- {0XFF4F,0X49},
- {0XFF50,0X02},
- {0XFF51,0X45},
- {0XFF52,0X00},
- {0XFF53,0X15},
- {0XFF54,0X03},
- {0XFF55,0X07},
- {0XFF56,0X00},
- {0XFF57,0X47},
- {0XFF58,0X02},
- {0XFF59,0XFF},
- {0XFF5A,0X03},
- {0XFF5B,0XFF},
- {0XFF5C,0XFD},
- {0XFF5D,0XFF},
- {0XFF68,0XFF},
- {0XFF69,0XFD},
- {0XFF6A,0XFF},
- {0XFF6B,0XFD},
- {0XFF6C,0XFD},
- {0XFF6D,0XFF},
- {0XFF6E,0XFD},
- {0XFF6F,0XFD},
- //GAMMA
- {0XFF80,0XC0},
- {0XFF81,0X00},
- {0XFF82,0X00},
- {0XFF83,0X03},
- {0XFF84,0X05},
- {0XFF85,0X0B},
- {0XFF86,0X12},
- {0XFF87,0X19},
- {0XFF88,0X21},
- {0XFF89,0X2A},
- {0XFF8A,0X33},
- {0XFF8B,0X3E},
- {0XFF8C,0X48},
- {0XFF8D,0X54},
- {0XFF8E,0X5F},
- {0XFF8F,0X6A},
- {0XFF90,0X74},
- {0XFF91,0X7F},
- {0XFF92,0X89},
- {0XFF93,0X93},
- {0XFF94,0X9E},
- {0XFF95,0XA9},
- {0XFF96,0XB3},
- {0XFF97,0XBD},
- {0XFF98,0XC6},
- {0XFF99,0XCE},
- {0XFF9A,0XD5},
- {0XFF9B,0XDC},
- {0XFF9C,0XE1},
- {0XFF9D,0XE7},
- {0XFF9E,0XEB},
- {0XFF9F,0XF0},
- {0XFFA0,0XF4},
- {0XFFA1,0XF8},
- //rgb_test_c
- {0XFFA8,0XFB},
- {0XFFA9,0X00},
- {0XFFAA,0X00},
- {0XFFAB,0X00},
- {0XFFAC,0X00},
- {0XFFAD,0X00},
- {0XFFC0,0X00},
- {0XFFC1,0X04},
- {0XFFC2,0X4C},
- {0XFFC3,0X02},
- {0XFFC4,0X5A},
- {0XFFC5,0X2C},
- {0XFFC6,0X74},
- {0XFFC7,0XDA},
- {0XFFC8,0X5C},
- {0XFFC9,0X10},
- {0XFFCA,0X43},
- {0XFFCB,0X6F},
- {0XFFCC,0X60},
- {0XFFCD,0X60},
- {0XFFCE,0X60},
- {0XFFCF,0X00},
- {0XFFD0,0X7E},
- {0XFFD1,0XEF},
- {0XFFD2,0XFF},
- {0XFFD3,0XFC},
- {0XFFD4,0X4E},
- {0XFFD5,0X22},
- {0XFFD6,0XE9},
- {0XFFD7,0X1B},
- {0XFFD8,0X00},
- {0XFFD9,0X00},
- {0XFFDA,0X00},
- {0XFFDB,0X00},
- {0XFFDC,0X00},
- {0XFFDD,0X00},
- {0XFFE8,0X00},
- {0XFFE9,0X4A},
- {0XFFEA,0X04},
- {0XFFEB,0X00},
- {0XFFEC,0X00},
- {0XFFED,0XFF},
- {0XFFEE,0XFF},
- {0XFFEF,0X00},
- };
- struct ark7116h {
- struct v4l2_ctrl_handler hdl;
- struct v4l2_subdev sd;
- struct gpio_desc *reset_gpio;
- u32 input;
- u8 brightness;
- u8 contrast;
- u8 saturation;
- u8 hue;
- struct i2c_client *client;
- unsigned short default_addr;
- PanlstaticPara *custom_para;
- };
- #define VIDIOC_GET_RESOLUTION _IOWR('V', BASE_VIDIOC_PRIVATE + 1, int)
- #define VIDIOC_GET_PROGRESSIVE _IOWR('V', BASE_VIDIOC_PRIVATE + 2, int)
- #define VIDIOC_GET_CHIPINFO _IOWR('V', BASE_VIDIOC_PRIVATE + 3, int)
- #define VIDIOC_GET_ITU601_ENABLE _IOWR('V', BASE_VIDIOC_PRIVATE + 6, int)
- static inline struct ark7116h *to_ark7116h(struct v4l2_subdev *sd)
- {
- return container_of(sd, struct ark7116h, sd);
- }
- static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
- {
- return &container_of(ctrl->handler, struct ark7116h, hdl)->sd;
- }
- static unsigned char to_slave_addr(unsigned char addr)
- {
- switch(addr) {
- case 0XF9:
- case 0XFD:
- return 0xB4;
- case 0XF3:
- return 0xE6;
- case 0XFA:
- return 0xBA;
- case 0XFB:
- return 0xB8;
- case 0XFC:
- return 0xB6;
- case 0XFE:
- return 0xB2;
- case 0XFF:
- return 0XB0;
- case 0X00:
- return 0xBE;
- default:
- return 0xBE;
- }
- }
- static unsigned char amt_read_reg(struct ark7116h *decoder, unsigned int reg)
- {
- struct v4l2_subdev *sd = &decoder->sd;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int rc;
- client->addr = to_slave_addr((reg >> 8) & 0xff) >> 1;
- rc = i2c_smbus_read_byte_data(client, reg & 0xff);
- client->addr = decoder->default_addr;
- if (rc < 0) {
- dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc);
- return rc;
- }
- dev_dbg(sd->dev, "ark7116h: read 0x%04x = %02x\n", reg, rc);
- return rc;
- }
- static int amt_write_reg(struct ark7116h *decoder, unsigned int reg, unsigned char value)
- {
- struct v4l2_subdev *sd = &decoder->sd;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int rc;
- client->addr = to_slave_addr((reg >> 8) & 0xff) >> 1;
- rc = i2c_smbus_write_byte_data(client, reg & 0xff, value);
- client->addr = decoder->default_addr;
- if (rc < 0)
- printk(KERN_ALERT "i2c i/o error: rc == %d\n", rc);
- #ifdef ARK7116H_DUMP_REGS
- client->addr = to_slave_addr((reg >> 8) & 0xff) >> 1;
- rc = i2c_smbus_read_byte_data(client, reg & 0xff);
- client->addr = decoder->default_addr;
- printk(KERN_ALERT "ark7116h: read 0x%04x = %02x\n", reg, rc);
- #endif
- return rc;
- }
- /****************************************************************************
- I2C Client & Driver
- ****************************************************************************/
- static int ark7116h_detect_signal(struct ark7116h *decoder)
- {
- return (amt_read_reg(decoder, ARK7116H_STATUS) & 0x2) == 0x2;
- }
- static int ark7116h_select_input(struct ark7116h *decoder, u32 input)
- {
- unsigned char val;
- if (input > ARK7116H_AV2)
- return -EINVAL;
- if (input == ARK7116H_AV0)
- val = 0;
- else if (input == ARK7116H_AV1)
- val = 0x10;
- else if (input == ARK7116H_AV2)
- val = 0x30;
- return amt_write_reg(decoder, ARK7116H_INPUT_CTL, val);
- }
- static int ark7116h_reset(struct ark7116h *decoder)
- {
- gpiod_set_value_cansleep(decoder->reset_gpio, 0);
- mdelay(1);
- gpiod_set_value_cansleep(decoder->reset_gpio, 1);
- mdelay(1);
- gpiod_set_value_cansleep(decoder->reset_gpio, 0);
- mdelay(10);
- return 0;
- };
- static void ark7116h_config_common(struct ark7116h *decoder)
- {
- int i;
- for (i = 0; i < sizeof(AV1_staticPara) / sizeof(AV1_staticPara[0]); i++)
- amt_write_reg(decoder, AV1_staticPara[i].addr, AV1_staticPara[i].value);
- }
- static int _ark7116h_init(struct ark7116h *decoder)
- {
- unsigned char val;
-
- reinit:
- ark7116h_reset(decoder);
- //soft reset 7116h
- amt_write_reg(decoder, 0xFB00, 0x5A);
- mdelay(10);
- amt_write_reg(decoder,0xC6, 0x40);
- val = amt_read_reg(decoder, 0xFAC6);
- val &= 0x80;
-
- if ( val != 0 ) {
- goto reinit;
- }
- ark7116h_config_common(decoder);
- //soft reset decoder
- val = amt_read_reg(decoder,0xFDA0);
- val |= 1;
- amt_write_reg(decoder,0xFDA0, val);
- mdelay(40);
- val &= ~1;
- amt_write_reg(decoder,0xFDA0, val);
- mdelay(40);
- ark7116h_select_input(decoder, decoder->input);
- return 0;
- }
- /* ----------------------------------------------------------------------- */
- static int ark7116h_s_ctrl(struct v4l2_ctrl *ctrl)
- {
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct ark7116h *decoder = to_ark7116h(sd);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- amt_write_reg(decoder, ARK7116H_BRIGHT_CTL, ctrl->val);
- return 0;
- case V4L2_CID_CONTRAST:
- amt_write_reg(decoder, ARK7116H_CONTRAST_CTL, ctrl->val);
- return 0;
- case V4L2_CID_SATURATION:
- amt_write_reg(decoder, ARK7116H_SATURATION_CTL, ctrl->val);
- return 0;
- case V4L2_CID_HUE:
- amt_write_reg(decoder, ARK7116H_HUE_CTL, ctrl->val);
- return 0;
- }
- return -EINVAL;
- }
- static int ark7116h_g_input_status(struct v4l2_subdev *sd, u32 *status)
- {
- struct ark7116h *decoder = to_ark7116h(sd);
- if (status) {
- *status = 0;
- if (!ark7116h_detect_signal(decoder))
- *status |= V4L2_IN_ST_NO_SIGNAL;
- }
- return 0;
- }
- static int ark7116h_s_routing(struct v4l2_subdev *sd, u32 input,
- u32 output, u32 config)
- {
- struct ark7116h *decoder = to_ark7116h(sd);
- ark7116h_select_input(decoder, input);
- decoder->input = input;
- return 0;
- }
- static int ark7116h_init(struct v4l2_subdev *sd, u32 val)
- {
- struct ark7116h *decoder = to_ark7116h(sd);
- int ret;
- ret=_ark7116h_init(decoder);
- if(ret){
- printk(KERN_ALERT "_ark7116h_init error.\n");
- }
- return ret;
- }
- static long ark7116h_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
- {
- int ret = 0;
- switch (cmd) {
- case VIDIOC_GET_RESOLUTION:
- {
- int* temp = (int *)arg;
- *temp = TYPE_CVBS;
- break;
- }
- case VIDIOC_GET_PROGRESSIVE:
- {
- int* temp = (int *)arg;
- *temp = 1;
- break;
- }
- case VIDIOC_GET_CHIPINFO:
- {
- int* temp = (int *)arg;
- *temp = TYPE_ARK7116H;
- break;
- }
- case VIDIOC_GET_ITU601_ENABLE:
- {
- int* temp = (int *)arg;
- *temp = 1;
- break;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return ret;
- }
- /* ----------------------------------------------------------------------- */
- static const struct v4l2_ctrl_ops ark7116h_ctrl_ops = {
- .s_ctrl = ark7116h_s_ctrl,
- };
- static const struct v4l2_subdev_video_ops ark7116h_video_ops = {
- .g_input_status = ark7116h_g_input_status,
- .s_routing = ark7116h_s_routing,
- };
- static const struct v4l2_subdev_core_ops ark7116h_core_ops = {
- .init = ark7116h_init,
- .ioctl = ark7116h_ioctl,
- };
- static const struct v4l2_subdev_ops ark7116h_ops = {
- .core = &ark7116h_core_ops,
- .video = &ark7116h_video_ops,
- };
- static int ark7116h_parse_dt(struct ark7116h *decoder, struct device_node *np)
- {
- int ret = 0;
- int value;
- if (of_property_read_u32(np, "default-channel", &decoder->input))
- decoder->input = 0;
- if(!of_property_read_u32(np, "carback-config", &value)) {
- if(value == 1){
- printk("Initialize in carback.\n");
- }
- else if(value == 0){
- ret=_ark7116h_init(decoder);
- if(ret){
- printk(KERN_ALERT "_ark7116h_init error.\n");
- }
- }
- }
- return ret;
- }
- static int ark7116h_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct ark7116h *decoder;
- struct v4l2_subdev *sd;
- struct device_node *np = client->dev.of_node;
- int res;
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -EIO;
- decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
- if (!decoder)
- return -ENOMEM;
- decoder->client = client;
- decoder->default_addr = client->addr;
- decoder->custom_para = (PanlstaticPara *)id->driver_data;
- sd = &decoder->sd;
- decoder->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(decoder->reset_gpio)) {
- res = PTR_ERR(decoder->reset_gpio);
- v4l_err(client, "request for reset pin failed: %d\n", res);
- return res;
- }
- res = ark7116h_parse_dt(decoder, np);
- if (res) {
- dev_err(sd->dev, "DT parsing error: %d\n", res);
- return res;
- }
- v4l2_i2c_subdev_init(sd, client, &ark7116h_ops);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- v4l2_ctrl_handler_init(&decoder->hdl, 4);
- v4l2_ctrl_new_std(&decoder->hdl, &ark7116h_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &ark7116h_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &ark7116h_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &ark7116h_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- sd->ctrl_handler = &decoder->hdl;
- if (decoder->hdl.error) {
- res = decoder->hdl.error;
- goto err;
- }
- res = v4l2_async_register_subdev(sd);
- if (res < 0)
- goto err;
-
- return 0;
- err:
- v4l2_ctrl_handler_free(&decoder->hdl);
- return res;
-
- printk("ark7116h_probe.\n");
-
- return 0;
- }
- static int ark7116h_remove(struct i2c_client *client)
- {
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ark7116h *decoder = to_ark7116h(sd);
- dev_dbg(sd->dev,
- "ark7116h.c: removing ark7116h adapter on address 0x%x\n",
- client->addr << 1);
- v4l2_async_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- return 0;
- }
- /* ----------------------------------------------------------------------- */
- /* the length of name must less than 20 */
- static const struct i2c_device_id ark7116h_id[] = {
- { "ark7116h_1668e_devb", NULL},
- { }
- };
- MODULE_DEVICE_TABLE(i2c, ark7116h_id);
- #if IS_ENABLED(CONFIG_OF)
- static const struct of_device_id ark7116h_of_match[] = {
- { .compatible = "arkmicro,ark7116h_1668e_devb", },
- { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, ark7116h_of_match);
- #endif
- static struct i2c_driver ark7116h_driver = {
- .driver = {
- .of_match_table = of_match_ptr(ark7116h_of_match),
- .name = "ark7116h",
- },
- .probe = ark7116h_probe,
- .remove = ark7116h_remove,
- .id_table = ark7116h_id,
- };
- static int __init ark_7116h_init(void)
- {
- return i2c_add_driver(&ark7116h_driver);
- }
- static void __exit ark_7116h_exit(void)
- {
- i2c_del_driver(&ark7116h_driver);
- }
- device_initcall(ark_7116h_init);
- MODULE_AUTHOR("arkmicro");
- MODULE_DESCRIPTION("arkmicro 7116h decoder driver for v4l2");
- MODULE_LICENSE("GPL v2");
|