dm365_ipipe.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862
  1. /*
  2. * Copyright (C) 2012 Texas Instruments Inc
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. *
  17. * Contributors:
  18. * Manjunath Hadli <manjunath.hadli@ti.com>
  19. * Prabhakar Lad <prabhakar.lad@ti.com>
  20. *
  21. *
  22. * IPIPE allows fine tuning of the input image using different
  23. * tuning modules in IPIPE. Some examples :- Noise filter, Defect
  24. * pixel correction etc. It essentially operate on Bayer Raw data
  25. * or YUV raw data. To do image tuning, application call,
  26. *
  27. */
  28. #include <linux/slab.h>
  29. #include "dm365_ipipe.h"
  30. #include "dm365_ipipe_hw.h"
  31. #include "vpfe_mc_capture.h"
  32. #define MIN_OUT_WIDTH 32
  33. #define MIN_OUT_HEIGHT 32
  34. /* ipipe input format's */
  35. static const unsigned int ipipe_input_fmts[] = {
  36. MEDIA_BUS_FMT_UYVY8_2X8,
  37. MEDIA_BUS_FMT_SGRBG12_1X12,
  38. MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
  39. MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
  40. };
  41. /* ipipe output format's */
  42. static const unsigned int ipipe_output_fmts[] = {
  43. MEDIA_BUS_FMT_UYVY8_2X8,
  44. };
  45. static int ipipe_validate_lutdpc_params(struct vpfe_ipipe_lutdpc *lutdpc)
  46. {
  47. int i;
  48. if (lutdpc->en > 1 || lutdpc->repl_white > 1 ||
  49. lutdpc->dpc_size > LUT_DPC_MAX_SIZE)
  50. return -EINVAL;
  51. if (lutdpc->en && !lutdpc->table)
  52. return -EINVAL;
  53. for (i = 0; i < lutdpc->dpc_size; i++)
  54. if (lutdpc->table[i].horz_pos > LUT_DPC_H_POS_MASK ||
  55. lutdpc->table[i].vert_pos > LUT_DPC_V_POS_MASK)
  56. return -EINVAL;
  57. return 0;
  58. }
  59. static int ipipe_set_lutdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
  60. {
  61. struct vpfe_ipipe_lutdpc *lutdpc = &ipipe->config.lutdpc;
  62. struct vpfe_ipipe_lutdpc *dpc_param;
  63. struct device *dev;
  64. if (!param) {
  65. memset((void *)lutdpc, 0, sizeof(struct vpfe_ipipe_lutdpc));
  66. goto success;
  67. }
  68. dev = ipipe->subdev.v4l2_dev->dev;
  69. dpc_param = param;
  70. lutdpc->en = dpc_param->en;
  71. lutdpc->repl_white = dpc_param->repl_white;
  72. lutdpc->dpc_size = dpc_param->dpc_size;
  73. memcpy(&lutdpc->table, &dpc_param->table,
  74. (dpc_param->dpc_size * sizeof(struct vpfe_ipipe_lutdpc_entry)));
  75. if (ipipe_validate_lutdpc_params(lutdpc) < 0)
  76. return -EINVAL;
  77. success:
  78. ipipe_set_lutdpc_regs(ipipe->base_addr, ipipe->isp5_base_addr, lutdpc);
  79. return 0;
  80. }
  81. static int ipipe_get_lutdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
  82. {
  83. struct vpfe_ipipe_lutdpc *lut_param = param;
  84. struct vpfe_ipipe_lutdpc *lutdpc = &ipipe->config.lutdpc;
  85. lut_param->en = lutdpc->en;
  86. lut_param->repl_white = lutdpc->repl_white;
  87. lut_param->dpc_size = lutdpc->dpc_size;
  88. memcpy(&lut_param->table, &lutdpc->table,
  89. (lutdpc->dpc_size * sizeof(struct vpfe_ipipe_lutdpc_entry)));
  90. return 0;
  91. }
  92. static int ipipe_set_input_config(struct vpfe_ipipe_device *ipipe, void *param)
  93. {
  94. struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
  95. if (!param)
  96. memset(config, 0, sizeof(struct vpfe_ipipe_input_config));
  97. else
  98. memcpy(config, param, sizeof(struct vpfe_ipipe_input_config));
  99. return 0;
  100. }
  101. static int ipipe_get_input_config(struct vpfe_ipipe_device *ipipe, void *param)
  102. {
  103. struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
  104. if (!param)
  105. return -EINVAL;
  106. memcpy(param, config, sizeof(struct vpfe_ipipe_input_config));
  107. return 0;
  108. }
  109. static int ipipe_validate_otfdpc_params(struct vpfe_ipipe_otfdpc *dpc_param)
  110. {
  111. struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0;
  112. struct vpfe_ipipe_otfdpc_3_0_cfg *dpc_3_0;
  113. if (dpc_param->en > 1)
  114. return -EINVAL;
  115. if (dpc_param->alg == VPFE_IPIPE_OTFDPC_2_0) {
  116. dpc_2_0 = &dpc_param->alg_cfg.dpc_2_0;
  117. if (dpc_2_0->det_thr.r > OTFDPC_DPC2_THR_MASK ||
  118. dpc_2_0->det_thr.gr > OTFDPC_DPC2_THR_MASK ||
  119. dpc_2_0->det_thr.gb > OTFDPC_DPC2_THR_MASK ||
  120. dpc_2_0->det_thr.b > OTFDPC_DPC2_THR_MASK ||
  121. dpc_2_0->corr_thr.r > OTFDPC_DPC2_THR_MASK ||
  122. dpc_2_0->corr_thr.gr > OTFDPC_DPC2_THR_MASK ||
  123. dpc_2_0->corr_thr.gb > OTFDPC_DPC2_THR_MASK ||
  124. dpc_2_0->corr_thr.b > OTFDPC_DPC2_THR_MASK)
  125. return -EINVAL;
  126. return 0;
  127. }
  128. dpc_3_0 = &dpc_param->alg_cfg.dpc_3_0;
  129. if (dpc_3_0->act_adj_shf > OTF_DPC3_0_SHF_MASK ||
  130. dpc_3_0->det_thr > OTF_DPC3_0_DET_MASK ||
  131. dpc_3_0->det_slp > OTF_DPC3_0_SLP_MASK ||
  132. dpc_3_0->det_thr_min > OTF_DPC3_0_DET_MASK ||
  133. dpc_3_0->det_thr_max > OTF_DPC3_0_DET_MASK ||
  134. dpc_3_0->corr_thr > OTF_DPC3_0_CORR_MASK ||
  135. dpc_3_0->corr_slp > OTF_DPC3_0_SLP_MASK ||
  136. dpc_3_0->corr_thr_min > OTF_DPC3_0_CORR_MASK ||
  137. dpc_3_0->corr_thr_max > OTF_DPC3_0_CORR_MASK)
  138. return -EINVAL;
  139. return 0;
  140. }
  141. static int ipipe_set_otfdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
  142. {
  143. struct vpfe_ipipe_otfdpc *dpc_param = param;
  144. struct vpfe_ipipe_otfdpc *otfdpc = &ipipe->config.otfdpc;
  145. struct device *dev;
  146. if (!param) {
  147. memset((void *)otfdpc, 0, sizeof(struct ipipe_otfdpc_2_0));
  148. goto success;
  149. }
  150. dev = ipipe->subdev.v4l2_dev->dev;
  151. memcpy(otfdpc, dpc_param, sizeof(struct vpfe_ipipe_otfdpc));
  152. if (ipipe_validate_otfdpc_params(otfdpc) < 0) {
  153. dev_err(dev, "Invalid otfdpc params\n");
  154. return -EINVAL;
  155. }
  156. success:
  157. ipipe_set_otfdpc_regs(ipipe->base_addr, otfdpc);
  158. return 0;
  159. }
  160. static int ipipe_get_otfdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
  161. {
  162. struct vpfe_ipipe_otfdpc *dpc_param = param;
  163. struct vpfe_ipipe_otfdpc *otfdpc = &ipipe->config.otfdpc;
  164. memcpy(dpc_param, otfdpc, sizeof(struct vpfe_ipipe_otfdpc));
  165. return 0;
  166. }
  167. static int ipipe_validate_nf_params(struct vpfe_ipipe_nf *nf_param)
  168. {
  169. int i;
  170. if (nf_param->en > 1 || nf_param->shft_val > D2F_SHFT_VAL_MASK ||
  171. nf_param->spread_val > D2F_SPR_VAL_MASK ||
  172. nf_param->apply_lsc_gain > 1 ||
  173. nf_param->edge_det_min_thr > D2F_EDGE_DET_THR_MASK ||
  174. nf_param->edge_det_max_thr > D2F_EDGE_DET_THR_MASK)
  175. return -EINVAL;
  176. for (i = 0; i < VPFE_IPIPE_NF_THR_TABLE_SIZE; i++)
  177. if (nf_param->thr[i] > D2F_THR_VAL_MASK)
  178. return -EINVAL;
  179. for (i = 0; i < VPFE_IPIPE_NF_STR_TABLE_SIZE; i++)
  180. if (nf_param->str[i] > D2F_STR_VAL_MASK)
  181. return -EINVAL;
  182. return 0;
  183. }
  184. static int ipipe_set_nf_params(struct vpfe_ipipe_device *ipipe,
  185. unsigned int id, void *param)
  186. {
  187. struct vpfe_ipipe_nf *nf_param = param;
  188. struct vpfe_ipipe_nf *nf = &ipipe->config.nf1;
  189. struct device *dev;
  190. if (id == IPIPE_D2F_2ND)
  191. nf = &ipipe->config.nf2;
  192. if (!nf_param) {
  193. memset((void *)nf, 0, sizeof(struct vpfe_ipipe_nf));
  194. goto success;
  195. }
  196. dev = ipipe->subdev.v4l2_dev->dev;
  197. memcpy(nf, nf_param, sizeof(struct vpfe_ipipe_nf));
  198. if (ipipe_validate_nf_params(nf) < 0) {
  199. dev_err(dev, "Invalid nf params\n");
  200. return -EINVAL;
  201. }
  202. success:
  203. ipipe_set_d2f_regs(ipipe->base_addr, id, nf);
  204. return 0;
  205. }
  206. static int ipipe_set_nf1_params(struct vpfe_ipipe_device *ipipe, void *param)
  207. {
  208. return ipipe_set_nf_params(ipipe, IPIPE_D2F_1ST, param);
  209. }
  210. static int ipipe_set_nf2_params(struct vpfe_ipipe_device *ipipe, void *param)
  211. {
  212. return ipipe_set_nf_params(ipipe, IPIPE_D2F_2ND, param);
  213. }
  214. static int ipipe_get_nf_params(struct vpfe_ipipe_device *ipipe,
  215. unsigned int id, void *param)
  216. {
  217. struct vpfe_ipipe_nf *nf_param = param;
  218. struct vpfe_ipipe_nf *nf = &ipipe->config.nf1;
  219. if (id == IPIPE_D2F_2ND)
  220. nf = &ipipe->config.nf2;
  221. memcpy(nf_param, nf, sizeof(struct vpfe_ipipe_nf));
  222. return 0;
  223. }
  224. static int ipipe_get_nf1_params(struct vpfe_ipipe_device *ipipe, void *param)
  225. {
  226. return ipipe_get_nf_params(ipipe, IPIPE_D2F_1ST, param);
  227. }
  228. static int ipipe_get_nf2_params(struct vpfe_ipipe_device *ipipe, void *param)
  229. {
  230. return ipipe_get_nf_params(ipipe, IPIPE_D2F_2ND, param);
  231. }
  232. static int ipipe_validate_gic_params(struct vpfe_ipipe_gic *gic)
  233. {
  234. if (gic->en > 1 || gic->gain > GIC_GAIN_MASK ||
  235. gic->thr > GIC_THR_MASK || gic->slope > GIC_SLOPE_MASK ||
  236. gic->apply_lsc_gain > 1 ||
  237. gic->nf2_thr_gain.integer > GIC_NFGAN_INT_MASK ||
  238. gic->nf2_thr_gain.decimal > GIC_NFGAN_DECI_MASK)
  239. return -EINVAL;
  240. return 0;
  241. }
  242. static int ipipe_set_gic_params(struct vpfe_ipipe_device *ipipe, void *param)
  243. {
  244. struct vpfe_ipipe_gic *gic_param = param;
  245. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  246. struct vpfe_ipipe_gic *gic = &ipipe->config.gic;
  247. if (!gic_param) {
  248. memset((void *)gic, 0, sizeof(struct vpfe_ipipe_gic));
  249. goto success;
  250. }
  251. memcpy(gic, gic_param, sizeof(struct vpfe_ipipe_gic));
  252. if (ipipe_validate_gic_params(gic) < 0) {
  253. dev_err(dev, "Invalid gic params\n");
  254. return -EINVAL;
  255. }
  256. success:
  257. ipipe_set_gic_regs(ipipe->base_addr, gic);
  258. return 0;
  259. }
  260. static int ipipe_get_gic_params(struct vpfe_ipipe_device *ipipe, void *param)
  261. {
  262. struct vpfe_ipipe_gic *gic_param = param;
  263. struct vpfe_ipipe_gic *gic = &ipipe->config.gic;
  264. memcpy(gic_param, gic, sizeof(struct vpfe_ipipe_gic));
  265. return 0;
  266. }
  267. static int ipipe_validate_wb_params(struct vpfe_ipipe_wb *wbal)
  268. {
  269. if (wbal->ofst_r > WB_OFFSET_MASK ||
  270. wbal->ofst_gr > WB_OFFSET_MASK ||
  271. wbal->ofst_gb > WB_OFFSET_MASK ||
  272. wbal->ofst_b > WB_OFFSET_MASK ||
  273. wbal->gain_r.integer > WB_GAIN_INT_MASK ||
  274. wbal->gain_r.decimal > WB_GAIN_DECI_MASK ||
  275. wbal->gain_gr.integer > WB_GAIN_INT_MASK ||
  276. wbal->gain_gr.decimal > WB_GAIN_DECI_MASK ||
  277. wbal->gain_gb.integer > WB_GAIN_INT_MASK ||
  278. wbal->gain_gb.decimal > WB_GAIN_DECI_MASK ||
  279. wbal->gain_b.integer > WB_GAIN_INT_MASK ||
  280. wbal->gain_b.decimal > WB_GAIN_DECI_MASK)
  281. return -EINVAL;
  282. return 0;
  283. }
  284. static int ipipe_set_wb_params(struct vpfe_ipipe_device *ipipe, void *param)
  285. {
  286. struct vpfe_ipipe_wb *wb_param = param;
  287. struct vpfe_ipipe_wb *wbal = &ipipe->config.wbal;
  288. if (!wb_param) {
  289. const struct vpfe_ipipe_wb wb_defaults = {
  290. .gain_r = {2, 0x0},
  291. .gain_gr = {2, 0x0},
  292. .gain_gb = {2, 0x0},
  293. .gain_b = {2, 0x0}
  294. };
  295. memcpy(wbal, &wb_defaults, sizeof(struct vpfe_ipipe_wb));
  296. goto success;
  297. }
  298. memcpy(wbal, wb_param, sizeof(struct vpfe_ipipe_wb));
  299. if (ipipe_validate_wb_params(wbal) < 0)
  300. return -EINVAL;
  301. success:
  302. ipipe_set_wb_regs(ipipe->base_addr, wbal);
  303. return 0;
  304. }
  305. static int ipipe_get_wb_params(struct vpfe_ipipe_device *ipipe, void *param)
  306. {
  307. struct vpfe_ipipe_wb *wb_param = param;
  308. struct vpfe_ipipe_wb *wbal = &ipipe->config.wbal;
  309. memcpy(wb_param, wbal, sizeof(struct vpfe_ipipe_wb));
  310. return 0;
  311. }
  312. static int ipipe_validate_cfa_params(struct vpfe_ipipe_cfa *cfa)
  313. {
  314. if (cfa->hpf_thr_2dir > CFA_HPF_THR_2DIR_MASK ||
  315. cfa->hpf_slp_2dir > CFA_HPF_SLOPE_2DIR_MASK ||
  316. cfa->hp_mix_thr_2dir > CFA_HPF_MIX_THR_2DIR_MASK ||
  317. cfa->hp_mix_slope_2dir > CFA_HPF_MIX_SLP_2DIR_MASK ||
  318. cfa->dir_thr_2dir > CFA_DIR_THR_2DIR_MASK ||
  319. cfa->dir_slope_2dir > CFA_DIR_SLP_2DIR_MASK ||
  320. cfa->nd_wt_2dir > CFA_ND_WT_2DIR_MASK ||
  321. cfa->hue_fract_daa > CFA_DAA_HUE_FRA_MASK ||
  322. cfa->edge_thr_daa > CFA_DAA_EDG_THR_MASK ||
  323. cfa->thr_min_daa > CFA_DAA_THR_MIN_MASK ||
  324. cfa->thr_slope_daa > CFA_DAA_THR_SLP_MASK ||
  325. cfa->slope_min_daa > CFA_DAA_SLP_MIN_MASK ||
  326. cfa->slope_slope_daa > CFA_DAA_SLP_SLP_MASK ||
  327. cfa->lp_wt_daa > CFA_DAA_LP_WT_MASK)
  328. return -EINVAL;
  329. return 0;
  330. }
  331. static int ipipe_set_cfa_params(struct vpfe_ipipe_device *ipipe, void *param)
  332. {
  333. struct vpfe_ipipe_cfa *cfa_param = param;
  334. struct vpfe_ipipe_cfa *cfa = &ipipe->config.cfa;
  335. if (!cfa_param) {
  336. memset(cfa, 0, sizeof(struct vpfe_ipipe_cfa));
  337. cfa->alg = VPFE_IPIPE_CFA_ALG_2DIRAC;
  338. goto success;
  339. }
  340. memcpy(cfa, cfa_param, sizeof(struct vpfe_ipipe_cfa));
  341. if (ipipe_validate_cfa_params(cfa) < 0)
  342. return -EINVAL;
  343. success:
  344. ipipe_set_cfa_regs(ipipe->base_addr, cfa);
  345. return 0;
  346. }
  347. static int ipipe_get_cfa_params(struct vpfe_ipipe_device *ipipe, void *param)
  348. {
  349. struct vpfe_ipipe_cfa *cfa_param = param;
  350. struct vpfe_ipipe_cfa *cfa = &ipipe->config.cfa;
  351. memcpy(cfa_param, cfa, sizeof(struct vpfe_ipipe_cfa));
  352. return 0;
  353. }
  354. static int
  355. ipipe_validate_rgb2rgb_params(struct vpfe_ipipe_rgb2rgb *rgb2rgb,
  356. unsigned int id)
  357. {
  358. u32 gain_int_upper = RGB2RGB_1_GAIN_INT_MASK;
  359. u32 offset_upper = RGB2RGB_1_OFST_MASK;
  360. if (id == IPIPE_RGB2RGB_2) {
  361. offset_upper = RGB2RGB_2_OFST_MASK;
  362. gain_int_upper = RGB2RGB_2_GAIN_INT_MASK;
  363. }
  364. if (rgb2rgb->coef_rr.decimal > RGB2RGB_GAIN_DECI_MASK ||
  365. rgb2rgb->coef_rr.integer > gain_int_upper)
  366. return -EINVAL;
  367. if (rgb2rgb->coef_gr.decimal > RGB2RGB_GAIN_DECI_MASK ||
  368. rgb2rgb->coef_gr.integer > gain_int_upper)
  369. return -EINVAL;
  370. if (rgb2rgb->coef_br.decimal > RGB2RGB_GAIN_DECI_MASK ||
  371. rgb2rgb->coef_br.integer > gain_int_upper)
  372. return -EINVAL;
  373. if (rgb2rgb->coef_rg.decimal > RGB2RGB_GAIN_DECI_MASK ||
  374. rgb2rgb->coef_rg.integer > gain_int_upper)
  375. return -EINVAL;
  376. if (rgb2rgb->coef_gg.decimal > RGB2RGB_GAIN_DECI_MASK ||
  377. rgb2rgb->coef_gg.integer > gain_int_upper)
  378. return -EINVAL;
  379. if (rgb2rgb->coef_bg.decimal > RGB2RGB_GAIN_DECI_MASK ||
  380. rgb2rgb->coef_bg.integer > gain_int_upper)
  381. return -EINVAL;
  382. if (rgb2rgb->coef_rb.decimal > RGB2RGB_GAIN_DECI_MASK ||
  383. rgb2rgb->coef_rb.integer > gain_int_upper)
  384. return -EINVAL;
  385. if (rgb2rgb->coef_gb.decimal > RGB2RGB_GAIN_DECI_MASK ||
  386. rgb2rgb->coef_gb.integer > gain_int_upper)
  387. return -EINVAL;
  388. if (rgb2rgb->coef_bb.decimal > RGB2RGB_GAIN_DECI_MASK ||
  389. rgb2rgb->coef_bb.integer > gain_int_upper)
  390. return -EINVAL;
  391. if (rgb2rgb->out_ofst_r > offset_upper ||
  392. rgb2rgb->out_ofst_g > offset_upper ||
  393. rgb2rgb->out_ofst_b > offset_upper)
  394. return -EINVAL;
  395. return 0;
  396. }
  397. static int ipipe_set_rgb2rgb_params(struct vpfe_ipipe_device *ipipe,
  398. unsigned int id, void *param)
  399. {
  400. struct vpfe_ipipe_rgb2rgb *rgb2rgb = &ipipe->config.rgb2rgb1;
  401. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  402. struct vpfe_ipipe_rgb2rgb *rgb2rgb_param;
  403. rgb2rgb_param = param;
  404. if (id == IPIPE_RGB2RGB_2)
  405. rgb2rgb = &ipipe->config.rgb2rgb2;
  406. if (!rgb2rgb_param) {
  407. const struct vpfe_ipipe_rgb2rgb rgb2rgb_defaults = {
  408. .coef_rr = {1, 0}, /* 256 */
  409. .coef_gr = {0, 0},
  410. .coef_br = {0, 0},
  411. .coef_rg = {0, 0},
  412. .coef_gg = {1, 0}, /* 256 */
  413. .coef_bg = {0, 0},
  414. .coef_rb = {0, 0},
  415. .coef_gb = {0, 0},
  416. .coef_bb = {1, 0}, /* 256 */
  417. };
  418. /* Copy defaults for rgb2rgb conversion */
  419. memcpy(rgb2rgb, &rgb2rgb_defaults,
  420. sizeof(struct vpfe_ipipe_rgb2rgb));
  421. goto success;
  422. }
  423. memcpy(rgb2rgb, rgb2rgb_param, sizeof(struct vpfe_ipipe_rgb2rgb));
  424. if (ipipe_validate_rgb2rgb_params(rgb2rgb, id) < 0) {
  425. dev_err(dev, "Invalid rgb2rgb params\n");
  426. return -EINVAL;
  427. }
  428. success:
  429. ipipe_set_rgb2rgb_regs(ipipe->base_addr, id, rgb2rgb);
  430. return 0;
  431. }
  432. static int
  433. ipipe_set_rgb2rgb_1_params(struct vpfe_ipipe_device *ipipe, void *param)
  434. {
  435. return ipipe_set_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_1, param);
  436. }
  437. static int
  438. ipipe_set_rgb2rgb_2_params(struct vpfe_ipipe_device *ipipe, void *param)
  439. {
  440. return ipipe_set_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_2, param);
  441. }
  442. static int ipipe_get_rgb2rgb_params(struct vpfe_ipipe_device *ipipe,
  443. unsigned int id, void *param)
  444. {
  445. struct vpfe_ipipe_rgb2rgb *rgb2rgb = &ipipe->config.rgb2rgb1;
  446. struct vpfe_ipipe_rgb2rgb *rgb2rgb_param;
  447. rgb2rgb_param = param;
  448. if (id == IPIPE_RGB2RGB_2)
  449. rgb2rgb = &ipipe->config.rgb2rgb2;
  450. memcpy(rgb2rgb_param, rgb2rgb, sizeof(struct vpfe_ipipe_rgb2rgb));
  451. return 0;
  452. }
  453. static int
  454. ipipe_get_rgb2rgb_1_params(struct vpfe_ipipe_device *ipipe, void *param)
  455. {
  456. return ipipe_get_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_1, param);
  457. }
  458. static int
  459. ipipe_get_rgb2rgb_2_params(struct vpfe_ipipe_device *ipipe, void *param)
  460. {
  461. return ipipe_get_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_2, param);
  462. }
  463. static int
  464. ipipe_validate_gamma_entry(struct vpfe_ipipe_gamma_entry *table, int size)
  465. {
  466. int i;
  467. if (!table)
  468. return -EINVAL;
  469. for (i = 0; i < size; i++)
  470. if (table[i].slope > GAMMA_MASK ||
  471. table[i].offset > GAMMA_MASK)
  472. return -EINVAL;
  473. return 0;
  474. }
  475. static int
  476. ipipe_validate_gamma_params(struct vpfe_ipipe_gamma *gamma, struct device *dev)
  477. {
  478. int table_size;
  479. int err;
  480. if (gamma->bypass_r > 1 ||
  481. gamma->bypass_b > 1 ||
  482. gamma->bypass_g > 1)
  483. return -EINVAL;
  484. if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
  485. return 0;
  486. table_size = gamma->tbl_size;
  487. if (!gamma->bypass_r) {
  488. err = ipipe_validate_gamma_entry(gamma->table_r, table_size);
  489. if (err) {
  490. dev_err(dev, "GAMMA R - table entry invalid\n");
  491. return err;
  492. }
  493. }
  494. if (!gamma->bypass_b) {
  495. err = ipipe_validate_gamma_entry(gamma->table_b, table_size);
  496. if (err) {
  497. dev_err(dev, "GAMMA B - table entry invalid\n");
  498. return err;
  499. }
  500. }
  501. if (!gamma->bypass_g) {
  502. err = ipipe_validate_gamma_entry(gamma->table_g, table_size);
  503. if (err) {
  504. dev_err(dev, "GAMMA G - table entry invalid\n");
  505. return err;
  506. }
  507. }
  508. return 0;
  509. }
  510. static int
  511. ipipe_set_gamma_params(struct vpfe_ipipe_device *ipipe, void *param)
  512. {
  513. struct vpfe_ipipe_gamma *gamma_param = param;
  514. struct vpfe_ipipe_gamma *gamma = &ipipe->config.gamma;
  515. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  516. int table_size;
  517. if (!gamma_param) {
  518. memset(gamma, 0, sizeof(struct vpfe_ipipe_gamma));
  519. gamma->tbl_sel = VPFE_IPIPE_GAMMA_TBL_ROM;
  520. goto success;
  521. }
  522. gamma->bypass_r = gamma_param->bypass_r;
  523. gamma->bypass_b = gamma_param->bypass_b;
  524. gamma->bypass_g = gamma_param->bypass_g;
  525. gamma->tbl_sel = gamma_param->tbl_sel;
  526. gamma->tbl_size = gamma_param->tbl_size;
  527. if (ipipe_validate_gamma_params(gamma, dev) < 0)
  528. return -EINVAL;
  529. if (gamma_param->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
  530. goto success;
  531. table_size = gamma->tbl_size;
  532. if (!gamma_param->bypass_r)
  533. memcpy(&gamma->table_r, &gamma_param->table_r,
  534. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  535. if (!gamma_param->bypass_b)
  536. memcpy(&gamma->table_b, &gamma_param->table_b,
  537. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  538. if (!gamma_param->bypass_g)
  539. memcpy(&gamma->table_g, &gamma_param->table_g,
  540. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  541. success:
  542. ipipe_set_gamma_regs(ipipe->base_addr, ipipe->isp5_base_addr, gamma);
  543. return 0;
  544. }
  545. static int ipipe_get_gamma_params(struct vpfe_ipipe_device *ipipe, void *param)
  546. {
  547. struct vpfe_ipipe_gamma *gamma_param = param;
  548. struct vpfe_ipipe_gamma *gamma = &ipipe->config.gamma;
  549. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  550. int table_size;
  551. gamma_param->bypass_r = gamma->bypass_r;
  552. gamma_param->bypass_g = gamma->bypass_g;
  553. gamma_param->bypass_b = gamma->bypass_b;
  554. gamma_param->tbl_sel = gamma->tbl_sel;
  555. gamma_param->tbl_size = gamma->tbl_size;
  556. if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
  557. return 0;
  558. table_size = gamma->tbl_size;
  559. if (!gamma->bypass_r && !gamma_param->table_r) {
  560. dev_err(dev,
  561. "ipipe_get_gamma_params: table ptr empty for R\n");
  562. return -EINVAL;
  563. }
  564. memcpy(gamma_param->table_r, gamma->table_r,
  565. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  566. if (!gamma->bypass_g && !gamma_param->table_g) {
  567. dev_err(dev, "ipipe_get_gamma_params: table ptr empty for G\n");
  568. return -EINVAL;
  569. }
  570. memcpy(gamma_param->table_g, gamma->table_g,
  571. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  572. if (!gamma->bypass_b && !gamma_param->table_b) {
  573. dev_err(dev, "ipipe_get_gamma_params: table ptr empty for B\n");
  574. return -EINVAL;
  575. }
  576. memcpy(gamma_param->table_b, gamma->table_b,
  577. (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
  578. return 0;
  579. }
  580. static int ipipe_validate_3d_lut_params(struct vpfe_ipipe_3d_lut *lut)
  581. {
  582. int i;
  583. if (!lut->en)
  584. return 0;
  585. for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++)
  586. if (lut->table[i].r > D3_LUT_ENTRY_MASK ||
  587. lut->table[i].g > D3_LUT_ENTRY_MASK ||
  588. lut->table[i].b > D3_LUT_ENTRY_MASK)
  589. return -EINVAL;
  590. return 0;
  591. }
  592. static int ipipe_get_3d_lut_params(struct vpfe_ipipe_device *ipipe, void *param)
  593. {
  594. struct vpfe_ipipe_3d_lut *lut_param = param;
  595. struct vpfe_ipipe_3d_lut *lut = &ipipe->config.lut;
  596. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  597. lut_param->en = lut->en;
  598. if (!lut_param->table) {
  599. dev_err(dev, "ipipe_get_3d_lut_params: Invalid table ptr\n");
  600. return -EINVAL;
  601. }
  602. memcpy(lut_param->table, &lut->table,
  603. (VPFE_IPIPE_MAX_SIZE_3D_LUT *
  604. sizeof(struct vpfe_ipipe_3d_lut_entry)));
  605. return 0;
  606. }
  607. static int
  608. ipipe_set_3d_lut_params(struct vpfe_ipipe_device *ipipe, void *param)
  609. {
  610. struct vpfe_ipipe_3d_lut *lut_param = param;
  611. struct vpfe_ipipe_3d_lut *lut = &ipipe->config.lut;
  612. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  613. if (!lut_param) {
  614. memset(lut, 0, sizeof(struct vpfe_ipipe_3d_lut));
  615. goto success;
  616. }
  617. memcpy(lut, lut_param, sizeof(struct vpfe_ipipe_3d_lut));
  618. if (ipipe_validate_3d_lut_params(lut) < 0) {
  619. dev_err(dev, "Invalid 3D-LUT Params\n");
  620. return -EINVAL;
  621. }
  622. success:
  623. ipipe_set_3d_lut_regs(ipipe->base_addr, ipipe->isp5_base_addr, lut);
  624. return 0;
  625. }
  626. static int ipipe_validate_rgb2yuv_params(struct vpfe_ipipe_rgb2yuv *rgb2yuv)
  627. {
  628. if (rgb2yuv->coef_ry.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  629. rgb2yuv->coef_ry.integer > RGB2YCBCR_COEF_INT_MASK)
  630. return -EINVAL;
  631. if (rgb2yuv->coef_gy.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  632. rgb2yuv->coef_gy.integer > RGB2YCBCR_COEF_INT_MASK)
  633. return -EINVAL;
  634. if (rgb2yuv->coef_by.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  635. rgb2yuv->coef_by.integer > RGB2YCBCR_COEF_INT_MASK)
  636. return -EINVAL;
  637. if (rgb2yuv->coef_rcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  638. rgb2yuv->coef_rcb.integer > RGB2YCBCR_COEF_INT_MASK)
  639. return -EINVAL;
  640. if (rgb2yuv->coef_gcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  641. rgb2yuv->coef_gcb.integer > RGB2YCBCR_COEF_INT_MASK)
  642. return -EINVAL;
  643. if (rgb2yuv->coef_bcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  644. rgb2yuv->coef_bcb.integer > RGB2YCBCR_COEF_INT_MASK)
  645. return -EINVAL;
  646. if (rgb2yuv->coef_rcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  647. rgb2yuv->coef_rcr.integer > RGB2YCBCR_COEF_INT_MASK)
  648. return -EINVAL;
  649. if (rgb2yuv->coef_gcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  650. rgb2yuv->coef_gcr.integer > RGB2YCBCR_COEF_INT_MASK)
  651. return -EINVAL;
  652. if (rgb2yuv->coef_bcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
  653. rgb2yuv->coef_bcr.integer > RGB2YCBCR_COEF_INT_MASK)
  654. return -EINVAL;
  655. if (rgb2yuv->out_ofst_y > RGB2YCBCR_OFST_MASK ||
  656. rgb2yuv->out_ofst_cb > RGB2YCBCR_OFST_MASK ||
  657. rgb2yuv->out_ofst_cr > RGB2YCBCR_OFST_MASK)
  658. return -EINVAL;
  659. return 0;
  660. }
  661. static int
  662. ipipe_set_rgb2yuv_params(struct vpfe_ipipe_device *ipipe, void *param)
  663. {
  664. struct vpfe_ipipe_rgb2yuv *rgb2yuv = &ipipe->config.rgb2yuv;
  665. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  666. struct vpfe_ipipe_rgb2yuv *rgb2yuv_param;
  667. rgb2yuv_param = param;
  668. if (!rgb2yuv_param) {
  669. /* Defaults for rgb2yuv conversion */
  670. const struct vpfe_ipipe_rgb2yuv rgb2yuv_defaults = {
  671. .coef_ry = {0, 0x4d},
  672. .coef_gy = {0, 0x96},
  673. .coef_by = {0, 0x1d},
  674. .coef_rcb = {0xf, 0xd5},
  675. .coef_gcb = {0xf, 0xab},
  676. .coef_bcb = {0, 0x80},
  677. .coef_rcr = {0, 0x80},
  678. .coef_gcr = {0xf, 0x95},
  679. .coef_bcr = {0xf, 0xeb},
  680. .out_ofst_cb = 0x80,
  681. .out_ofst_cr = 0x80,
  682. };
  683. /* Copy defaults for rgb2yuv conversion */
  684. memcpy(rgb2yuv, &rgb2yuv_defaults,
  685. sizeof(struct vpfe_ipipe_rgb2yuv));
  686. goto success;
  687. }
  688. memcpy(rgb2yuv, rgb2yuv_param, sizeof(struct vpfe_ipipe_rgb2yuv));
  689. if (ipipe_validate_rgb2yuv_params(rgb2yuv) < 0) {
  690. dev_err(dev, "Invalid rgb2yuv params\n");
  691. return -EINVAL;
  692. }
  693. success:
  694. ipipe_set_rgb2ycbcr_regs(ipipe->base_addr, rgb2yuv);
  695. return 0;
  696. }
  697. static int
  698. ipipe_get_rgb2yuv_params(struct vpfe_ipipe_device *ipipe, void *param)
  699. {
  700. struct vpfe_ipipe_rgb2yuv *rgb2yuv = &ipipe->config.rgb2yuv;
  701. struct vpfe_ipipe_rgb2yuv *rgb2yuv_param;
  702. rgb2yuv_param = param;
  703. memcpy(rgb2yuv_param, rgb2yuv, sizeof(struct vpfe_ipipe_rgb2yuv));
  704. return 0;
  705. }
  706. static int ipipe_validate_gbce_params(struct vpfe_ipipe_gbce *gbce)
  707. {
  708. u32 max = GBCE_Y_VAL_MASK;
  709. int i;
  710. if (!gbce->en)
  711. return 0;
  712. if (gbce->type == VPFE_IPIPE_GBCE_GAIN_TBL)
  713. max = GBCE_GAIN_VAL_MASK;
  714. for (i = 0; i < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; i++)
  715. if (gbce->table[i] > max)
  716. return -EINVAL;
  717. return 0;
  718. }
  719. static int ipipe_set_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
  720. {
  721. struct vpfe_ipipe_gbce *gbce_param = param;
  722. struct vpfe_ipipe_gbce *gbce = &ipipe->config.gbce;
  723. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  724. if (!gbce_param) {
  725. memset(gbce, 0, sizeof(struct vpfe_ipipe_gbce));
  726. } else {
  727. memcpy(gbce, gbce_param, sizeof(struct vpfe_ipipe_gbce));
  728. if (ipipe_validate_gbce_params(gbce) < 0) {
  729. dev_err(dev, "Invalid gbce params\n");
  730. return -EINVAL;
  731. }
  732. }
  733. ipipe_set_gbce_regs(ipipe->base_addr, ipipe->isp5_base_addr, gbce);
  734. return 0;
  735. }
  736. static int ipipe_get_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
  737. {
  738. struct vpfe_ipipe_gbce *gbce_param = param;
  739. struct vpfe_ipipe_gbce *gbce = &ipipe->config.gbce;
  740. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  741. gbce_param->en = gbce->en;
  742. gbce_param->type = gbce->type;
  743. if (!gbce_param->table) {
  744. dev_err(dev, "ipipe_get_gbce_params: Invalid table ptr\n");
  745. return -EINVAL;
  746. }
  747. memcpy(gbce_param->table, gbce->table,
  748. (VPFE_IPIPE_MAX_SIZE_GBCE_LUT * sizeof(unsigned short)));
  749. return 0;
  750. }
  751. static int
  752. ipipe_validate_yuv422_conv_params(struct vpfe_ipipe_yuv422_conv *yuv422_conv)
  753. {
  754. if (yuv422_conv->en_chrom_lpf > 1)
  755. return -EINVAL;
  756. return 0;
  757. }
  758. static int
  759. ipipe_set_yuv422_conv_params(struct vpfe_ipipe_device *ipipe, void *param)
  760. {
  761. struct vpfe_ipipe_yuv422_conv *yuv422_conv = &ipipe->config.yuv422_conv;
  762. struct vpfe_ipipe_yuv422_conv *yuv422_conv_param;
  763. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  764. yuv422_conv_param = param;
  765. if (!yuv422_conv_param) {
  766. memset(yuv422_conv, 0, sizeof(struct vpfe_ipipe_yuv422_conv));
  767. yuv422_conv->chrom_pos = VPFE_IPIPE_YUV422_CHR_POS_COSITE;
  768. } else {
  769. memcpy(yuv422_conv, yuv422_conv_param,
  770. sizeof(struct vpfe_ipipe_yuv422_conv));
  771. if (ipipe_validate_yuv422_conv_params(yuv422_conv) < 0) {
  772. dev_err(dev, "Invalid yuv422 params\n");
  773. return -EINVAL;
  774. }
  775. }
  776. ipipe_set_yuv422_conv_regs(ipipe->base_addr, yuv422_conv);
  777. return 0;
  778. }
  779. static int
  780. ipipe_get_yuv422_conv_params(struct vpfe_ipipe_device *ipipe, void *param)
  781. {
  782. struct vpfe_ipipe_yuv422_conv *yuv422_conv = &ipipe->config.yuv422_conv;
  783. struct vpfe_ipipe_yuv422_conv *yuv422_conv_param;
  784. yuv422_conv_param = param;
  785. memcpy(yuv422_conv_param, yuv422_conv,
  786. sizeof(struct vpfe_ipipe_yuv422_conv));
  787. return 0;
  788. }
  789. static int ipipe_validate_yee_params(struct vpfe_ipipe_yee *yee)
  790. {
  791. int i;
  792. if (yee->en > 1 ||
  793. yee->en_halo_red > 1 ||
  794. yee->hpf_shft > YEE_HPF_SHIFT_MASK)
  795. return -EINVAL;
  796. if (yee->hpf_coef_00 > YEE_COEF_MASK ||
  797. yee->hpf_coef_01 > YEE_COEF_MASK ||
  798. yee->hpf_coef_02 > YEE_COEF_MASK ||
  799. yee->hpf_coef_10 > YEE_COEF_MASK ||
  800. yee->hpf_coef_11 > YEE_COEF_MASK ||
  801. yee->hpf_coef_12 > YEE_COEF_MASK ||
  802. yee->hpf_coef_20 > YEE_COEF_MASK ||
  803. yee->hpf_coef_21 > YEE_COEF_MASK ||
  804. yee->hpf_coef_22 > YEE_COEF_MASK)
  805. return -EINVAL;
  806. if (yee->yee_thr > YEE_THR_MASK ||
  807. yee->es_gain > YEE_ES_GAIN_MASK ||
  808. yee->es_thr1 > YEE_ES_THR1_MASK ||
  809. yee->es_thr2 > YEE_THR_MASK ||
  810. yee->es_gain_grad > YEE_THR_MASK ||
  811. yee->es_ofst_grad > YEE_THR_MASK)
  812. return -EINVAL;
  813. for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT; i++)
  814. if (yee->table[i] > YEE_ENTRY_MASK)
  815. return -EINVAL;
  816. return 0;
  817. }
  818. static int ipipe_set_yee_params(struct vpfe_ipipe_device *ipipe, void *param)
  819. {
  820. struct vpfe_ipipe_yee *yee_param = param;
  821. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  822. struct vpfe_ipipe_yee *yee = &ipipe->config.yee;
  823. if (!yee_param) {
  824. memset(yee, 0, sizeof(struct vpfe_ipipe_yee));
  825. } else {
  826. memcpy(yee, yee_param, sizeof(struct vpfe_ipipe_yee));
  827. if (ipipe_validate_yee_params(yee) < 0) {
  828. dev_err(dev, "Invalid yee params\n");
  829. return -EINVAL;
  830. }
  831. }
  832. ipipe_set_ee_regs(ipipe->base_addr, ipipe->isp5_base_addr, yee);
  833. return 0;
  834. }
  835. static int ipipe_get_yee_params(struct vpfe_ipipe_device *ipipe, void *param)
  836. {
  837. struct vpfe_ipipe_yee *yee_param = param;
  838. struct vpfe_ipipe_yee *yee = &ipipe->config.yee;
  839. yee_param->en = yee->en;
  840. yee_param->en_halo_red = yee->en_halo_red;
  841. yee_param->merge_meth = yee->merge_meth;
  842. yee_param->hpf_shft = yee->hpf_shft;
  843. yee_param->hpf_coef_00 = yee->hpf_coef_00;
  844. yee_param->hpf_coef_01 = yee->hpf_coef_01;
  845. yee_param->hpf_coef_02 = yee->hpf_coef_02;
  846. yee_param->hpf_coef_10 = yee->hpf_coef_10;
  847. yee_param->hpf_coef_11 = yee->hpf_coef_11;
  848. yee_param->hpf_coef_12 = yee->hpf_coef_12;
  849. yee_param->hpf_coef_20 = yee->hpf_coef_20;
  850. yee_param->hpf_coef_21 = yee->hpf_coef_21;
  851. yee_param->hpf_coef_22 = yee->hpf_coef_22;
  852. yee_param->yee_thr = yee->yee_thr;
  853. yee_param->es_gain = yee->es_gain;
  854. yee_param->es_thr1 = yee->es_thr1;
  855. yee_param->es_thr2 = yee->es_thr2;
  856. yee_param->es_gain_grad = yee->es_gain_grad;
  857. yee_param->es_ofst_grad = yee->es_ofst_grad;
  858. memcpy(yee_param->table, &yee->table,
  859. (VPFE_IPIPE_MAX_SIZE_YEE_LUT * sizeof(short)));
  860. return 0;
  861. }
  862. static int ipipe_validate_car_params(struct vpfe_ipipe_car *car)
  863. {
  864. if (car->en > 1 || car->hpf_shft > CAR_HPF_SHIFT_MASK ||
  865. car->gain1.shft > CAR_GAIN1_SHFT_MASK ||
  866. car->gain1.gain_min > CAR_GAIN_MIN_MASK ||
  867. car->gain2.shft > CAR_GAIN2_SHFT_MASK ||
  868. car->gain2.gain_min > CAR_GAIN_MIN_MASK)
  869. return -EINVAL;
  870. return 0;
  871. }
  872. static int ipipe_set_car_params(struct vpfe_ipipe_device *ipipe, void *param)
  873. {
  874. struct vpfe_ipipe_car *car_param = param;
  875. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  876. struct vpfe_ipipe_car *car = &ipipe->config.car;
  877. if (!car_param) {
  878. memset(car, 0, sizeof(struct vpfe_ipipe_car));
  879. } else {
  880. memcpy(car, car_param, sizeof(struct vpfe_ipipe_car));
  881. if (ipipe_validate_car_params(car) < 0) {
  882. dev_err(dev, "Invalid car params\n");
  883. return -EINVAL;
  884. }
  885. }
  886. ipipe_set_car_regs(ipipe->base_addr, car);
  887. return 0;
  888. }
  889. static int ipipe_get_car_params(struct vpfe_ipipe_device *ipipe, void *param)
  890. {
  891. struct vpfe_ipipe_car *car_param = param;
  892. struct vpfe_ipipe_car *car = &ipipe->config.car;
  893. memcpy(car_param, car, sizeof(struct vpfe_ipipe_car));
  894. return 0;
  895. }
  896. static int ipipe_validate_cgs_params(struct vpfe_ipipe_cgs *cgs)
  897. {
  898. if (cgs->en > 1 || cgs->h_shft > CAR_SHIFT_MASK)
  899. return -EINVAL;
  900. return 0;
  901. }
  902. static int ipipe_set_cgs_params(struct vpfe_ipipe_device *ipipe, void *param)
  903. {
  904. struct vpfe_ipipe_cgs *cgs_param = param;
  905. struct device *dev = ipipe->subdev.v4l2_dev->dev;
  906. struct vpfe_ipipe_cgs *cgs = &ipipe->config.cgs;
  907. if (!cgs_param) {
  908. memset(cgs, 0, sizeof(struct vpfe_ipipe_cgs));
  909. } else {
  910. memcpy(cgs, cgs_param, sizeof(struct vpfe_ipipe_cgs));
  911. if (ipipe_validate_cgs_params(cgs) < 0) {
  912. dev_err(dev, "Invalid cgs params\n");
  913. return -EINVAL;
  914. }
  915. }
  916. ipipe_set_cgs_regs(ipipe->base_addr, cgs);
  917. return 0;
  918. }
  919. static int ipipe_get_cgs_params(struct vpfe_ipipe_device *ipipe, void *param)
  920. {
  921. struct vpfe_ipipe_cgs *cgs_param = param;
  922. struct vpfe_ipipe_cgs *cgs = &ipipe->config.cgs;
  923. memcpy(cgs_param, cgs, sizeof(struct vpfe_ipipe_cgs));
  924. return 0;
  925. }
  926. static const struct ipipe_module_if ipipe_modules[VPFE_IPIPE_MAX_MODULES] = {
  927. /* VPFE_IPIPE_INPUT_CONFIG */ {
  928. offsetof(struct ipipe_module_params, input_config),
  929. FIELD_SIZEOF(struct ipipe_module_params, input_config),
  930. offsetof(struct vpfe_ipipe_config, input_config),
  931. ipipe_set_input_config,
  932. ipipe_get_input_config,
  933. }, /* VPFE_IPIPE_LUTDPC */ {
  934. offsetof(struct ipipe_module_params, lutdpc),
  935. FIELD_SIZEOF(struct ipipe_module_params, lutdpc),
  936. offsetof(struct vpfe_ipipe_config, lutdpc),
  937. ipipe_set_lutdpc_params,
  938. ipipe_get_lutdpc_params,
  939. }, /* VPFE_IPIPE_OTFDPC */ {
  940. offsetof(struct ipipe_module_params, otfdpc),
  941. FIELD_SIZEOF(struct ipipe_module_params, otfdpc),
  942. offsetof(struct vpfe_ipipe_config, otfdpc),
  943. ipipe_set_otfdpc_params,
  944. ipipe_get_otfdpc_params,
  945. }, /* VPFE_IPIPE_NF1 */ {
  946. offsetof(struct ipipe_module_params, nf1),
  947. FIELD_SIZEOF(struct ipipe_module_params, nf1),
  948. offsetof(struct vpfe_ipipe_config, nf1),
  949. ipipe_set_nf1_params,
  950. ipipe_get_nf1_params,
  951. }, /* VPFE_IPIPE_NF2 */ {
  952. offsetof(struct ipipe_module_params, nf2),
  953. FIELD_SIZEOF(struct ipipe_module_params, nf2),
  954. offsetof(struct vpfe_ipipe_config, nf2),
  955. ipipe_set_nf2_params,
  956. ipipe_get_nf2_params,
  957. }, /* VPFE_IPIPE_WB */ {
  958. offsetof(struct ipipe_module_params, wbal),
  959. FIELD_SIZEOF(struct ipipe_module_params, wbal),
  960. offsetof(struct vpfe_ipipe_config, wbal),
  961. ipipe_set_wb_params,
  962. ipipe_get_wb_params,
  963. }, /* VPFE_IPIPE_RGB2RGB_1 */ {
  964. offsetof(struct ipipe_module_params, rgb2rgb1),
  965. FIELD_SIZEOF(struct ipipe_module_params, rgb2rgb1),
  966. offsetof(struct vpfe_ipipe_config, rgb2rgb1),
  967. ipipe_set_rgb2rgb_1_params,
  968. ipipe_get_rgb2rgb_1_params,
  969. }, /* VPFE_IPIPE_RGB2RGB_2 */ {
  970. offsetof(struct ipipe_module_params, rgb2rgb2),
  971. FIELD_SIZEOF(struct ipipe_module_params, rgb2rgb2),
  972. offsetof(struct vpfe_ipipe_config, rgb2rgb2),
  973. ipipe_set_rgb2rgb_2_params,
  974. ipipe_get_rgb2rgb_2_params,
  975. }, /* VPFE_IPIPE_GAMMA */ {
  976. offsetof(struct ipipe_module_params, gamma),
  977. FIELD_SIZEOF(struct ipipe_module_params, gamma),
  978. offsetof(struct vpfe_ipipe_config, gamma),
  979. ipipe_set_gamma_params,
  980. ipipe_get_gamma_params,
  981. }, /* VPFE_IPIPE_3D_LUT */ {
  982. offsetof(struct ipipe_module_params, lut),
  983. FIELD_SIZEOF(struct ipipe_module_params, lut),
  984. offsetof(struct vpfe_ipipe_config, lut),
  985. ipipe_set_3d_lut_params,
  986. ipipe_get_3d_lut_params,
  987. }, /* VPFE_IPIPE_RGB2YUV */ {
  988. offsetof(struct ipipe_module_params, rgb2yuv),
  989. FIELD_SIZEOF(struct ipipe_module_params, rgb2yuv),
  990. offsetof(struct vpfe_ipipe_config, rgb2yuv),
  991. ipipe_set_rgb2yuv_params,
  992. ipipe_get_rgb2yuv_params,
  993. }, /* VPFE_IPIPE_YUV422_CONV */ {
  994. offsetof(struct ipipe_module_params, yuv422_conv),
  995. FIELD_SIZEOF(struct ipipe_module_params, yuv422_conv),
  996. offsetof(struct vpfe_ipipe_config, yuv422_conv),
  997. ipipe_set_yuv422_conv_params,
  998. ipipe_get_yuv422_conv_params,
  999. }, /* VPFE_IPIPE_YEE */ {
  1000. offsetof(struct ipipe_module_params, yee),
  1001. FIELD_SIZEOF(struct ipipe_module_params, yee),
  1002. offsetof(struct vpfe_ipipe_config, yee),
  1003. ipipe_set_yee_params,
  1004. ipipe_get_yee_params,
  1005. }, /* VPFE_IPIPE_GIC */ {
  1006. offsetof(struct ipipe_module_params, gic),
  1007. FIELD_SIZEOF(struct ipipe_module_params, gic),
  1008. offsetof(struct vpfe_ipipe_config, gic),
  1009. ipipe_set_gic_params,
  1010. ipipe_get_gic_params,
  1011. }, /* VPFE_IPIPE_CFA */ {
  1012. offsetof(struct ipipe_module_params, cfa),
  1013. FIELD_SIZEOF(struct ipipe_module_params, cfa),
  1014. offsetof(struct vpfe_ipipe_config, cfa),
  1015. ipipe_set_cfa_params,
  1016. ipipe_get_cfa_params,
  1017. }, /* VPFE_IPIPE_CAR */ {
  1018. offsetof(struct ipipe_module_params, car),
  1019. FIELD_SIZEOF(struct ipipe_module_params, car),
  1020. offsetof(struct vpfe_ipipe_config, car),
  1021. ipipe_set_car_params,
  1022. ipipe_get_car_params,
  1023. }, /* VPFE_IPIPE_CGS */ {
  1024. offsetof(struct ipipe_module_params, cgs),
  1025. FIELD_SIZEOF(struct ipipe_module_params, cgs),
  1026. offsetof(struct vpfe_ipipe_config, cgs),
  1027. ipipe_set_cgs_params,
  1028. ipipe_get_cgs_params,
  1029. }, /* VPFE_IPIPE_GBCE */ {
  1030. offsetof(struct ipipe_module_params, gbce),
  1031. FIELD_SIZEOF(struct ipipe_module_params, gbce),
  1032. offsetof(struct vpfe_ipipe_config, gbce),
  1033. ipipe_set_gbce_params,
  1034. ipipe_get_gbce_params,
  1035. },
  1036. };
  1037. static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
  1038. {
  1039. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1040. unsigned int i;
  1041. int rval = 0;
  1042. for (i = 0; i < ARRAY_SIZE(ipipe_modules); i++) {
  1043. unsigned int bit = 1 << i;
  1044. if (cfg->flag & bit) {
  1045. const struct ipipe_module_if *module_if =
  1046. &ipipe_modules[i];
  1047. struct ipipe_module_params *params;
  1048. void __user *from = *(void * __user *)
  1049. ((void *)cfg + module_if->config_offset);
  1050. size_t size;
  1051. void *to;
  1052. params = kmalloc(sizeof(struct ipipe_module_params),
  1053. GFP_KERNEL);
  1054. to = (void *)params + module_if->param_offset;
  1055. size = module_if->param_size;
  1056. if (to && from && size) {
  1057. if (copy_from_user(to, from, size)) {
  1058. rval = -EFAULT;
  1059. break;
  1060. }
  1061. rval = module_if->set(ipipe, to);
  1062. if (rval)
  1063. goto error;
  1064. } else if (to && !from && size) {
  1065. rval = module_if->set(ipipe, NULL);
  1066. if (rval)
  1067. goto error;
  1068. }
  1069. kfree(params);
  1070. }
  1071. }
  1072. error:
  1073. return rval;
  1074. }
  1075. static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
  1076. {
  1077. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1078. unsigned int i;
  1079. int rval = 0;
  1080. for (i = 1; i < ARRAY_SIZE(ipipe_modules); i++) {
  1081. unsigned int bit = 1 << i;
  1082. if (cfg->flag & bit) {
  1083. const struct ipipe_module_if *module_if =
  1084. &ipipe_modules[i];
  1085. struct ipipe_module_params *params;
  1086. void __user *to = *(void * __user *)
  1087. ((void *)cfg + module_if->config_offset);
  1088. size_t size;
  1089. void *from;
  1090. params = kmalloc(sizeof(struct ipipe_module_params),
  1091. GFP_KERNEL);
  1092. from = (void *)params + module_if->param_offset;
  1093. size = module_if->param_size;
  1094. if (to && from && size) {
  1095. rval = module_if->get(ipipe, from);
  1096. if (rval)
  1097. goto error;
  1098. if (copy_to_user(to, from, size)) {
  1099. rval = -EFAULT;
  1100. break;
  1101. }
  1102. }
  1103. kfree(params);
  1104. }
  1105. }
  1106. error:
  1107. return rval;
  1108. }
  1109. /*
  1110. * ipipe_ioctl() - Handle ipipe module private ioctl's
  1111. * @sd: pointer to v4l2 subdev structure
  1112. * @cmd: configuration command
  1113. * @arg: configuration argument
  1114. */
  1115. static long ipipe_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
  1116. {
  1117. int ret = 0;
  1118. switch (cmd) {
  1119. case VIDIOC_VPFE_IPIPE_S_CONFIG:
  1120. ret = ipipe_s_config(sd, arg);
  1121. break;
  1122. case VIDIOC_VPFE_IPIPE_G_CONFIG:
  1123. ret = ipipe_g_config(sd, arg);
  1124. break;
  1125. default:
  1126. ret = -ENOIOCTLCMD;
  1127. }
  1128. return ret;
  1129. }
  1130. void vpfe_ipipe_enable(struct vpfe_device *vpfe_dev, int en)
  1131. {
  1132. struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
  1133. struct vpfe_ipipe_device *ipipe = &vpfe_dev->vpfe_ipipe;
  1134. unsigned char val;
  1135. if (ipipe->input == IPIPE_INPUT_NONE)
  1136. return;
  1137. /* ipipe is set to single shot */
  1138. if (ipipeif->input == IPIPEIF_INPUT_MEMORY && en) {
  1139. /* for single-shot mode, need to wait for h/w to
  1140. * reset many register bits
  1141. */
  1142. do {
  1143. val = regr_ip(vpfe_dev->vpfe_ipipe.base_addr,
  1144. IPIPE_SRC_EN);
  1145. } while (val);
  1146. }
  1147. regw_ip(vpfe_dev->vpfe_ipipe.base_addr, en, IPIPE_SRC_EN);
  1148. }
  1149. /*
  1150. * ipipe_set_stream() - Enable/Disable streaming on the ipipe subdevice
  1151. * @sd: pointer to v4l2 subdev structure
  1152. * @enable: 1 == Enable, 0 == Disable
  1153. */
  1154. static int ipipe_set_stream(struct v4l2_subdev *sd, int enable)
  1155. {
  1156. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1157. struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
  1158. if (enable && ipipe->input != IPIPE_INPUT_NONE &&
  1159. ipipe->output != IPIPE_OUTPUT_NONE) {
  1160. if (config_ipipe_hw(ipipe) < 0)
  1161. return -EINVAL;
  1162. }
  1163. vpfe_ipipe_enable(vpfe_dev, enable);
  1164. return 0;
  1165. }
  1166. /*
  1167. * __ipipe_get_format() - helper function for getting ipipe format
  1168. * @ipipe: pointer to ipipe private structure.
  1169. * @pad: pad number.
  1170. * @cfg: V4L2 subdev pad config
  1171. * @which: wanted subdev format.
  1172. *
  1173. */
  1174. static struct v4l2_mbus_framefmt *
  1175. __ipipe_get_format(struct vpfe_ipipe_device *ipipe,
  1176. struct v4l2_subdev_pad_config *cfg, unsigned int pad,
  1177. enum v4l2_subdev_format_whence which)
  1178. {
  1179. if (which == V4L2_SUBDEV_FORMAT_TRY)
  1180. return v4l2_subdev_get_try_format(&ipipe->subdev, cfg, pad);
  1181. return &ipipe->formats[pad];
  1182. }
  1183. /*
  1184. * ipipe_try_format() - Handle try format by pad subdev method
  1185. * @ipipe: VPFE ipipe device.
  1186. * @cfg: V4L2 subdev pad config
  1187. * @pad: pad num.
  1188. * @fmt: pointer to v4l2 format structure.
  1189. * @which : wanted subdev format
  1190. */
  1191. static void
  1192. ipipe_try_format(struct vpfe_ipipe_device *ipipe,
  1193. struct v4l2_subdev_pad_config *cfg, unsigned int pad,
  1194. struct v4l2_mbus_framefmt *fmt,
  1195. enum v4l2_subdev_format_whence which)
  1196. {
  1197. unsigned int max_out_height;
  1198. unsigned int max_out_width;
  1199. unsigned int i;
  1200. max_out_width = IPIPE_MAX_OUTPUT_WIDTH_A;
  1201. max_out_height = IPIPE_MAX_OUTPUT_HEIGHT_A;
  1202. if (pad == IPIPE_PAD_SINK) {
  1203. for (i = 0; i < ARRAY_SIZE(ipipe_input_fmts); i++)
  1204. if (fmt->code == ipipe_input_fmts[i])
  1205. break;
  1206. /* If not found, use SBGGR10 as default */
  1207. if (i >= ARRAY_SIZE(ipipe_input_fmts))
  1208. fmt->code = MEDIA_BUS_FMT_SGRBG12_1X12;
  1209. } else if (pad == IPIPE_PAD_SOURCE) {
  1210. for (i = 0; i < ARRAY_SIZE(ipipe_output_fmts); i++)
  1211. if (fmt->code == ipipe_output_fmts[i])
  1212. break;
  1213. /* If not found, use UYVY as default */
  1214. if (i >= ARRAY_SIZE(ipipe_output_fmts))
  1215. fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
  1216. }
  1217. fmt->width = clamp_t(u32, fmt->width, MIN_OUT_HEIGHT, max_out_width);
  1218. fmt->height = clamp_t(u32, fmt->height, MIN_OUT_WIDTH, max_out_height);
  1219. }
  1220. /*
  1221. * ipipe_set_format() - Handle set format by pads subdev method
  1222. * @sd: pointer to v4l2 subdev structure
  1223. * @cfg: V4L2 subdev pad config
  1224. * @fmt: pointer to v4l2 subdev format structure
  1225. * return -EINVAL or zero on success
  1226. */
  1227. static int
  1228. ipipe_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
  1229. struct v4l2_subdev_format *fmt)
  1230. {
  1231. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1232. struct v4l2_mbus_framefmt *format;
  1233. format = __ipipe_get_format(ipipe, cfg, fmt->pad, fmt->which);
  1234. if (format == NULL)
  1235. return -EINVAL;
  1236. ipipe_try_format(ipipe, cfg, fmt->pad, &fmt->format, fmt->which);
  1237. *format = fmt->format;
  1238. if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
  1239. return 0;
  1240. if (fmt->pad == IPIPE_PAD_SINK &&
  1241. (ipipe->input == IPIPE_INPUT_CCDC ||
  1242. ipipe->input == IPIPE_INPUT_MEMORY))
  1243. ipipe->formats[fmt->pad] = fmt->format;
  1244. else if (fmt->pad == IPIPE_PAD_SOURCE &&
  1245. ipipe->output == IPIPE_OUTPUT_RESIZER)
  1246. ipipe->formats[fmt->pad] = fmt->format;
  1247. else
  1248. return -EINVAL;
  1249. return 0;
  1250. }
  1251. /*
  1252. * ipipe_get_format() - Handle get format by pads subdev method.
  1253. * @sd: pointer to v4l2 subdev structure.
  1254. * @cfg: V4L2 subdev pad config
  1255. * @fmt: pointer to v4l2 subdev format structure.
  1256. */
  1257. static int
  1258. ipipe_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
  1259. struct v4l2_subdev_format *fmt)
  1260. {
  1261. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1262. if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
  1263. fmt->format = ipipe->formats[fmt->pad];
  1264. else
  1265. fmt->format = *(v4l2_subdev_get_try_format(sd, cfg, fmt->pad));
  1266. return 0;
  1267. }
  1268. /*
  1269. * ipipe_enum_frame_size() - enum frame sizes on pads
  1270. * @sd: pointer to v4l2 subdev structure.
  1271. * @cfg: V4L2 subdev pad config
  1272. * @fse: pointer to v4l2_subdev_frame_size_enum structure.
  1273. */
  1274. static int
  1275. ipipe_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
  1276. struct v4l2_subdev_frame_size_enum *fse)
  1277. {
  1278. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1279. struct v4l2_mbus_framefmt format;
  1280. if (fse->index != 0)
  1281. return -EINVAL;
  1282. format.code = fse->code;
  1283. format.width = 1;
  1284. format.height = 1;
  1285. ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which);
  1286. fse->min_width = format.width;
  1287. fse->min_height = format.height;
  1288. if (format.code != fse->code)
  1289. return -EINVAL;
  1290. format.code = fse->code;
  1291. format.width = -1;
  1292. format.height = -1;
  1293. ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which);
  1294. fse->max_width = format.width;
  1295. fse->max_height = format.height;
  1296. return 0;
  1297. }
  1298. /*
  1299. * ipipe_enum_mbus_code() - enum mbus codes for pads
  1300. * @sd: pointer to v4l2 subdev structure.
  1301. * @cfg: V4L2 subdev pad config
  1302. * @code: pointer to v4l2_subdev_mbus_code_enum structure
  1303. */
  1304. static int
  1305. ipipe_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
  1306. struct v4l2_subdev_mbus_code_enum *code)
  1307. {
  1308. switch (code->pad) {
  1309. case IPIPE_PAD_SINK:
  1310. if (code->index >= ARRAY_SIZE(ipipe_input_fmts))
  1311. return -EINVAL;
  1312. code->code = ipipe_input_fmts[code->index];
  1313. break;
  1314. case IPIPE_PAD_SOURCE:
  1315. if (code->index >= ARRAY_SIZE(ipipe_output_fmts))
  1316. return -EINVAL;
  1317. code->code = ipipe_output_fmts[code->index];
  1318. break;
  1319. default:
  1320. return -EINVAL;
  1321. }
  1322. return 0;
  1323. }
  1324. /*
  1325. * ipipe_s_ctrl() - Handle set control subdev method
  1326. * @ctrl: pointer to v4l2 control structure
  1327. */
  1328. static int ipipe_s_ctrl(struct v4l2_ctrl *ctrl)
  1329. {
  1330. struct vpfe_ipipe_device *ipipe =
  1331. container_of(ctrl->handler, struct vpfe_ipipe_device, ctrls);
  1332. struct ipipe_lum_adj *lum_adj = &ipipe->config.lum_adj;
  1333. switch (ctrl->id) {
  1334. case V4L2_CID_BRIGHTNESS:
  1335. lum_adj->brightness = ctrl->val;
  1336. ipipe_set_lum_adj_regs(ipipe->base_addr, lum_adj);
  1337. break;
  1338. case V4L2_CID_CONTRAST:
  1339. lum_adj->contrast = ctrl->val;
  1340. ipipe_set_lum_adj_regs(ipipe->base_addr, lum_adj);
  1341. break;
  1342. default:
  1343. return -EINVAL;
  1344. }
  1345. return 0;
  1346. }
  1347. /*
  1348. * ipipe_init_formats() - Initialize formats on all pads
  1349. * @sd: pointer to v4l2 subdev structure.
  1350. * @fh: V4L2 subdev file handle
  1351. *
  1352. * Initialize all pad formats with default values. Try formats are initialized
  1353. * on the file handle.
  1354. */
  1355. static int
  1356. ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  1357. {
  1358. struct v4l2_subdev_format format;
  1359. memset(&format, 0, sizeof(format));
  1360. format.pad = IPIPE_PAD_SINK;
  1361. format.which = V4L2_SUBDEV_FORMAT_TRY;
  1362. format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
  1363. format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
  1364. format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
  1365. ipipe_set_format(sd, fh->pad, &format);
  1366. memset(&format, 0, sizeof(format));
  1367. format.pad = IPIPE_PAD_SOURCE;
  1368. format.which = V4L2_SUBDEV_FORMAT_TRY;
  1369. format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
  1370. format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
  1371. format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
  1372. ipipe_set_format(sd, fh->pad, &format);
  1373. return 0;
  1374. }
  1375. /* subdev core operations */
  1376. static const struct v4l2_subdev_core_ops ipipe_v4l2_core_ops = {
  1377. .ioctl = ipipe_ioctl,
  1378. };
  1379. static const struct v4l2_ctrl_ops ipipe_ctrl_ops = {
  1380. .s_ctrl = ipipe_s_ctrl,
  1381. };
  1382. /* subdev file operations */
  1383. static const struct v4l2_subdev_internal_ops ipipe_v4l2_internal_ops = {
  1384. .open = ipipe_init_formats,
  1385. };
  1386. /* subdev video operations */
  1387. static const struct v4l2_subdev_video_ops ipipe_v4l2_video_ops = {
  1388. .s_stream = ipipe_set_stream,
  1389. };
  1390. /* subdev pad operations */
  1391. static const struct v4l2_subdev_pad_ops ipipe_v4l2_pad_ops = {
  1392. .enum_mbus_code = ipipe_enum_mbus_code,
  1393. .enum_frame_size = ipipe_enum_frame_size,
  1394. .get_fmt = ipipe_get_format,
  1395. .set_fmt = ipipe_set_format,
  1396. };
  1397. /* v4l2 subdev operation */
  1398. static const struct v4l2_subdev_ops ipipe_v4l2_ops = {
  1399. .core = &ipipe_v4l2_core_ops,
  1400. .video = &ipipe_v4l2_video_ops,
  1401. .pad = &ipipe_v4l2_pad_ops,
  1402. };
  1403. /*
  1404. * Media entity operations
  1405. */
  1406. /*
  1407. * ipipe_link_setup() - Setup ipipe connections
  1408. * @entity: ipipe media entity
  1409. * @local: Pad at the local end of the link
  1410. * @remote: Pad at the remote end of the link
  1411. * @flags: Link flags
  1412. *
  1413. * return -EINVAL or zero on success
  1414. */
  1415. static int
  1416. ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
  1417. const struct media_pad *remote, u32 flags)
  1418. {
  1419. struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
  1420. struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
  1421. struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
  1422. u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
  1423. switch (local->index | media_entity_type(remote->entity)) {
  1424. case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
  1425. if (!(flags & MEDIA_LNK_FL_ENABLED)) {
  1426. ipipe->input = IPIPE_INPUT_NONE;
  1427. break;
  1428. }
  1429. if (ipipe->input != IPIPE_INPUT_NONE)
  1430. return -EBUSY;
  1431. if (ipipeif_sink == IPIPEIF_INPUT_MEMORY)
  1432. ipipe->input = IPIPE_INPUT_MEMORY;
  1433. else
  1434. ipipe->input = IPIPE_INPUT_CCDC;
  1435. break;
  1436. case IPIPE_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
  1437. /* out to RESIZER */
  1438. if (flags & MEDIA_LNK_FL_ENABLED)
  1439. ipipe->output = IPIPE_OUTPUT_RESIZER;
  1440. else
  1441. ipipe->output = IPIPE_OUTPUT_NONE;
  1442. break;
  1443. default:
  1444. return -EINVAL;
  1445. }
  1446. return 0;
  1447. }
  1448. static const struct media_entity_operations ipipe_media_ops = {
  1449. .link_setup = ipipe_link_setup,
  1450. };
  1451. /*
  1452. * vpfe_ipipe_unregister_entities() - ipipe unregister entity
  1453. * @vpfe_ipipe: pointer to ipipe subdevice structure.
  1454. */
  1455. void vpfe_ipipe_unregister_entities(struct vpfe_ipipe_device *vpfe_ipipe)
  1456. {
  1457. /* unregister subdev */
  1458. v4l2_device_unregister_subdev(&vpfe_ipipe->subdev);
  1459. /* cleanup entity */
  1460. media_entity_cleanup(&vpfe_ipipe->subdev.entity);
  1461. }
  1462. /*
  1463. * vpfe_ipipe_register_entities() - ipipe register entity
  1464. * @ipipe: pointer to ipipe subdevice structure.
  1465. * @vdev: pointer to v4l2 device structure.
  1466. */
  1467. int
  1468. vpfe_ipipe_register_entities(struct vpfe_ipipe_device *ipipe,
  1469. struct v4l2_device *vdev)
  1470. {
  1471. int ret;
  1472. /* Register the subdev */
  1473. ret = v4l2_device_register_subdev(vdev, &ipipe->subdev);
  1474. if (ret) {
  1475. pr_err("Failed to register ipipe as v4l2 subdevice\n");
  1476. return ret;
  1477. }
  1478. return ret;
  1479. }
  1480. #define IPIPE_CONTRAST_HIGH 0xff
  1481. #define IPIPE_BRIGHT_HIGH 0xff
  1482. /*
  1483. * vpfe_ipipe_init() - ipipe module initialization.
  1484. * @ipipe: pointer to ipipe subdevice structure.
  1485. * @pdev: platform device pointer.
  1486. */
  1487. int
  1488. vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
  1489. {
  1490. struct media_pad *pads = &ipipe->pads[0];
  1491. struct v4l2_subdev *sd = &ipipe->subdev;
  1492. struct media_entity *me = &sd->entity;
  1493. static resource_size_t res_len;
  1494. struct resource *res;
  1495. res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
  1496. if (!res)
  1497. return -ENOENT;
  1498. res_len = resource_size(res);
  1499. res = request_mem_region(res->start, res_len, res->name);
  1500. if (!res)
  1501. return -EBUSY;
  1502. ipipe->base_addr = ioremap_nocache(res->start, res_len);
  1503. if (!ipipe->base_addr)
  1504. return -EBUSY;
  1505. res = platform_get_resource(pdev, IORESOURCE_MEM, 6);
  1506. if (!res)
  1507. return -ENOENT;
  1508. ipipe->isp5_base_addr = ioremap_nocache(res->start, res_len);
  1509. if (!ipipe->isp5_base_addr)
  1510. return -EBUSY;
  1511. v4l2_subdev_init(sd, &ipipe_v4l2_ops);
  1512. sd->internal_ops = &ipipe_v4l2_internal_ops;
  1513. strlcpy(sd->name, "DAVINCI IPIPE", sizeof(sd->name));
  1514. sd->grp_id = 1 << 16; /* group ID for davinci subdevs */
  1515. v4l2_set_subdevdata(sd, ipipe);
  1516. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  1517. pads[IPIPE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
  1518. pads[IPIPE_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
  1519. ipipe->input = IPIPE_INPUT_NONE;
  1520. ipipe->output = IPIPE_OUTPUT_NONE;
  1521. me->ops = &ipipe_media_ops;
  1522. v4l2_ctrl_handler_init(&ipipe->ctrls, 2);
  1523. v4l2_ctrl_new_std(&ipipe->ctrls, &ipipe_ctrl_ops,
  1524. V4L2_CID_BRIGHTNESS, 0,
  1525. IPIPE_BRIGHT_HIGH, 1, 16);
  1526. v4l2_ctrl_new_std(&ipipe->ctrls, &ipipe_ctrl_ops,
  1527. V4L2_CID_CONTRAST, 0,
  1528. IPIPE_CONTRAST_HIGH, 1, 16);
  1529. v4l2_ctrl_handler_setup(&ipipe->ctrls);
  1530. sd->ctrl_handler = &ipipe->ctrls;
  1531. return media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
  1532. }
  1533. /*
  1534. * vpfe_ipipe_cleanup() - ipipe subdevice cleanup.
  1535. * @ipipe: pointer to ipipe subdevice
  1536. * @dev: pointer to platform device
  1537. */
  1538. void vpfe_ipipe_cleanup(struct vpfe_ipipe_device *ipipe,
  1539. struct platform_device *pdev)
  1540. {
  1541. struct resource *res;
  1542. v4l2_ctrl_handler_free(&ipipe->ctrls);
  1543. iounmap(ipipe->base_addr);
  1544. iounmap(ipipe->isp5_base_addr);
  1545. res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
  1546. if (res)
  1547. release_mem_region(res->start, resource_size(res));
  1548. }