dw-csi-sysfs.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.
  4. *
  5. * Synopsys DesignWare MIPI CSI-2 Host controller driver.
  6. * SysFS components for the platform driver
  7. *
  8. * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
  9. */
  10. #include "dw-mipi-csi.h"
  11. #include "bm_csi_hw.h"
  12. static ssize_t core_version_show(struct device *dev,
  13. struct device_attribute *attr,
  14. char *buf)
  15. {
  16. struct platform_device *pdev = to_platform_device(dev);
  17. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  18. struct dw_csi *csi_dev = &drvdata->csi_dev;
  19. char buffer[10];
  20. snprintf(buffer, 10, "v.%d.%d*\n", csi_dev->hw_version_major,
  21. csi_dev->hw_version_minor);
  22. return strlcpy(buf, buffer, PAGE_SIZE);
  23. }
  24. static ssize_t n_lanes_store(struct device *dev, struct device_attribute *attr,
  25. const char *buf, size_t count)
  26. {
  27. int ret;
  28. unsigned long lanes;
  29. struct platform_device *pdev = to_platform_device(dev);
  30. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  31. struct dw_csi *csi_dev = &drvdata->csi_dev;
  32. ret = kstrtoul(buf, 10, &lanes);
  33. if (ret < 0)
  34. return ret;
  35. if (lanes > 8) {
  36. dev_err(dev, "Invalid number of lanes %lu\n", lanes);
  37. return count;
  38. }
  39. dev_info(dev, "Lanes %lu\n", lanes);
  40. csi_dev->hw.num_lanes = lanes;
  41. return count;
  42. }
  43. static ssize_t n_lanes_show(struct device *dev,
  44. struct device_attribute *attr,
  45. char *buf)
  46. {
  47. struct platform_device *pdev = to_platform_device(dev);
  48. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  49. struct dw_csi *csi_dev = &drvdata->csi_dev;
  50. char buffer[10];
  51. snprintf(buffer, 10, "%d\n", csi_dev->hw.num_lanes);
  52. return strlcpy(buf, buffer, PAGE_SIZE);
  53. }
  54. static ssize_t width_store(struct device *dev, struct device_attribute *attr,
  55. const char *buf, size_t count)
  56. {
  57. int ret;
  58. unsigned long width;
  59. struct platform_device *pdev = to_platform_device(dev);
  60. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  61. struct dw_csi *csi_dev = &drvdata->csi_dev;
  62. ret = kstrtoul(buf, 10, &width);
  63. if (ret < 0)
  64. return ret;
  65. dev_info(dev, "width %lu\n", width);
  66. csi_dev->hw.htotal = width;
  67. return count;
  68. }
  69. static ssize_t width_show(struct device *dev,
  70. struct device_attribute *attr,
  71. char *buf)
  72. {
  73. struct platform_device *pdev = to_platform_device(dev);
  74. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  75. struct dw_csi *csi_dev = &drvdata->csi_dev;
  76. char buffer[10];
  77. snprintf(buffer, 10, "%d\n", csi_dev->hw.htotal);
  78. return strlcpy(buf, buffer, PAGE_SIZE);
  79. }
  80. static ssize_t height_store(struct device *dev, struct device_attribute *attr,
  81. const char *buf, size_t count)
  82. {
  83. int ret;
  84. unsigned long height;
  85. struct platform_device *pdev = to_platform_device(dev);
  86. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  87. struct dw_csi *csi_dev = &drvdata->csi_dev;
  88. ret = kstrtoul(buf, 10, &height);
  89. if (ret < 0)
  90. return ret;
  91. dev_info(dev, "hight %lu\n", height);
  92. csi_dev->hw.vactive = height;
  93. return count;
  94. }
  95. static ssize_t height_show(struct device *dev,
  96. struct device_attribute *attr,
  97. char *buf)
  98. {
  99. struct platform_device *pdev = to_platform_device(dev);
  100. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  101. struct dw_csi *csi_dev = &drvdata->csi_dev;
  102. char buffer[10];
  103. snprintf(buffer, 10, "%d\n", csi_dev->hw.vactive);
  104. return strlcpy(buf, buffer, PAGE_SIZE);
  105. }
  106. static ssize_t core_reset_show(struct device *dev,
  107. struct device_attribute *attr,
  108. char *buf)
  109. {
  110. struct platform_device *pdev = to_platform_device(dev);
  111. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  112. struct dw_csi *csi_dev = &drvdata->csi_dev;
  113. char buffer[10];
  114. /* Reset Controller and DPHY */
  115. phy_reset(csi_dev->phy);
  116. dw_mipi_csi_reset(csi_dev);
  117. snprintf(buffer, 10, "Reset\n");
  118. return strlcpy(buf, buffer, PAGE_SIZE);
  119. }
  120. static ssize_t data_type_store(struct device *dev,
  121. struct device_attribute *attr,
  122. const char *buf, size_t count)
  123. {
  124. int ret;
  125. unsigned long dt;
  126. struct platform_device *pdev = to_platform_device(dev);
  127. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  128. struct dw_csi *csi_dev = &drvdata->csi_dev;
  129. ret = kstrtoul(buf, 16, &dt);
  130. if (ret < 0)
  131. return ret;
  132. if (dt < 0x18 || dt > 0x2F) {
  133. dev_err(dev, "Invalid data type %lx\n", dt);
  134. return count;
  135. }
  136. dev_info(dev, "Data type 0x%lx\n", dt);
  137. csi_dev->ipi_dt = dt;
  138. dw_mipi_csi_set_ipi_fmt(csi_dev);
  139. return count;
  140. }
  141. static ssize_t data_type_show(struct device *dev,
  142. struct device_attribute *attr,
  143. char *buf)
  144. {
  145. struct platform_device *pdev = to_platform_device(dev);
  146. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  147. struct dw_csi *csi_dev = &drvdata->csi_dev;
  148. char buffer[10];
  149. snprintf(buffer, 10, "%x\n", csi_dev->ipi_dt);
  150. return strlcpy(buf, buffer, PAGE_SIZE);
  151. }
  152. /*******************************************/
  153. static ssize_t hsa_store(struct device *dev,
  154. struct device_attribute *attr,
  155. const char *buf, size_t count)
  156. {
  157. int ret;
  158. unsigned long hsa;
  159. struct platform_device *pdev = to_platform_device(dev);
  160. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  161. struct dw_csi *csi_dev = &drvdata->csi_dev;
  162. ret = kstrtoul(buf, 16, &hsa);
  163. if (ret < 0)
  164. return ret;
  165. if (hsa > 0xFFF) {
  166. dev_err(dev, "Invalid HSA time %lx\n", hsa);
  167. return count;
  168. }
  169. dev_info(dev, "HSA time 0x%lx\n", hsa);
  170. csi_dev->hw.hsa = hsa;
  171. return count;
  172. }
  173. static ssize_t hsa_show(struct device *dev,
  174. struct device_attribute *attr,
  175. char *buf)
  176. {
  177. struct platform_device *pdev = to_platform_device(dev);
  178. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  179. struct dw_csi *csi_dev = &drvdata->csi_dev;
  180. char buffer[10];
  181. snprintf(buffer, 10, "%x\n", csi_dev->hw.hsa);
  182. return strlcpy(buf, buffer, PAGE_SIZE);
  183. }
  184. static ssize_t hbp_store(struct device *dev,
  185. struct device_attribute *attr,
  186. const char *buf, size_t count)
  187. {
  188. int ret;
  189. unsigned long hbp;
  190. struct platform_device *pdev = to_platform_device(dev);
  191. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  192. struct dw_csi *csi_dev = &drvdata->csi_dev;
  193. ret = kstrtoul(buf, 16, &hbp);
  194. if (ret < 0)
  195. return ret;
  196. if (hbp > 0xFFF) {
  197. dev_err(dev, "Invalid HBP time %lx\n", hbp);
  198. return count;
  199. }
  200. dev_info(dev, "HBP time 0x%lx\n", hbp);
  201. csi_dev->hw.hbp = hbp;
  202. return count;
  203. }
  204. static ssize_t hbp_show(struct device *dev,
  205. struct device_attribute *attr,
  206. char *buf)
  207. {
  208. struct platform_device *pdev = to_platform_device(dev);
  209. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  210. struct dw_csi *csi_dev = &drvdata->csi_dev;
  211. char buffer[10];
  212. snprintf(buffer, 10, "%x\n", csi_dev->hw.hbp);
  213. return strlcpy(buf, buffer, PAGE_SIZE);
  214. }
  215. static ssize_t hsd_store(struct device *dev,
  216. struct device_attribute *attr,
  217. const char *buf, size_t count)
  218. {
  219. int ret;
  220. unsigned long hsd;
  221. struct platform_device *pdev = to_platform_device(dev);
  222. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  223. struct dw_csi *csi_dev = &drvdata->csi_dev;
  224. ret = kstrtoul(buf, 16, &hsd);
  225. if (ret < 0)
  226. return ret;
  227. if (hsd > 0xFFF) {
  228. dev_err(dev, "Invalid HSD time %lx\n", hsd);
  229. return count;
  230. }
  231. dev_info(dev, "HSD time 0x%lx\n", hsd);
  232. csi_dev->hw.hsd = hsd;
  233. return count;
  234. }
  235. static ssize_t hsd_show(struct device *dev,
  236. struct device_attribute *attr,
  237. char *buf)
  238. {
  239. struct platform_device *pdev = to_platform_device(dev);
  240. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  241. struct dw_csi *csi_dev = &drvdata->csi_dev;
  242. char buffer[10];
  243. snprintf(buffer, 10, "%x\n", csi_dev->hw.hsd);
  244. return strlcpy(buf, buffer, PAGE_SIZE);
  245. }
  246. static ssize_t ipi2_hsa_store(struct device *dev,
  247. struct device_attribute *attr,
  248. const char *buf, size_t count)
  249. {
  250. int ret;
  251. unsigned long hsa;
  252. struct platform_device *pdev = to_platform_device(dev);
  253. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  254. struct dw_csi *csi_dev = &drvdata->csi_dev;
  255. ret = kstrtoul(buf, 16, &hsa);
  256. if (ret < 0)
  257. return ret;
  258. if (hsa > 0xFFF) {
  259. dev_err(dev, "Invalid HSA time %lx\n", hsa);
  260. return count;
  261. }
  262. dev_info(dev, "HSA time 0x%lx\n", hsa);
  263. csi_dev->hw.ipi2_hsa = hsa;
  264. return count;
  265. }
  266. static ssize_t ipi2_hsa_show(struct device *dev,
  267. struct device_attribute *attr,
  268. char *buf)
  269. {
  270. struct platform_device *pdev = to_platform_device(dev);
  271. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  272. struct dw_csi *csi_dev = &drvdata->csi_dev;
  273. char buffer[10];
  274. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hsa);
  275. return strlcpy(buf, buffer, PAGE_SIZE);
  276. }
  277. static ssize_t ipi2_hbp_store(struct device *dev,
  278. struct device_attribute *attr,
  279. const char *buf, size_t count)
  280. {
  281. int ret;
  282. unsigned long hbp;
  283. struct platform_device *pdev = to_platform_device(dev);
  284. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  285. struct dw_csi *csi_dev = &drvdata->csi_dev;
  286. ret = kstrtoul(buf, 16, &hbp);
  287. if (ret < 0)
  288. return ret;
  289. if (hbp > 0xFFF) {
  290. dev_err(dev, "Invalid HBP time %lx\n", hbp);
  291. return count;
  292. }
  293. dev_info(dev, "HBP time 0x%lx\n", hbp);
  294. csi_dev->hw.ipi2_hbp = hbp;
  295. return count;
  296. }
  297. static ssize_t ipi2_hbp_show(struct device *dev,
  298. struct device_attribute *attr,
  299. char *buf)
  300. {
  301. struct platform_device *pdev = to_platform_device(dev);
  302. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  303. struct dw_csi *csi_dev = &drvdata->csi_dev;
  304. char buffer[10];
  305. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hbp);
  306. return strlcpy(buf, buffer, PAGE_SIZE);
  307. }
  308. static ssize_t ipi2_hsd_store(struct device *dev,
  309. struct device_attribute *attr,
  310. const char *buf, size_t count)
  311. {
  312. int ret;
  313. unsigned long hsd;
  314. struct platform_device *pdev = to_platform_device(dev);
  315. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  316. struct dw_csi *csi_dev = &drvdata->csi_dev;
  317. ret = kstrtoul(buf, 16, &hsd);
  318. if (ret < 0)
  319. return ret;
  320. if (hsd > 0xFFF) {
  321. dev_err(dev, "Invalid HSD time %lx\n", hsd);
  322. return count;
  323. }
  324. dev_info(dev, "HSD time 0x%lx\n", hsd);
  325. csi_dev->hw.ipi2_hsd = hsd;
  326. return count;
  327. }
  328. static ssize_t ipi2_hsd_show(struct device *dev,
  329. struct device_attribute *attr,
  330. char *buf)
  331. {
  332. struct platform_device *pdev = to_platform_device(dev);
  333. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  334. struct dw_csi *csi_dev = &drvdata->csi_dev;
  335. char buffer[10];
  336. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hsd);
  337. return strlcpy(buf, buffer, PAGE_SIZE);
  338. }
  339. static ssize_t ipi3_hsa_store(struct device *dev,
  340. struct device_attribute *attr,
  341. const char *buf, size_t count)
  342. {
  343. int ret;
  344. unsigned long hsa;
  345. struct platform_device *pdev = to_platform_device(dev);
  346. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  347. struct dw_csi *csi_dev = &drvdata->csi_dev;
  348. ret = kstrtoul(buf, 16, &hsa);
  349. if (ret < 0)
  350. return ret;
  351. if (hsa > 0xFFF) {
  352. dev_err(dev, "Invalid HSA time %lx\n", hsa);
  353. return count;
  354. }
  355. dev_info(dev, "HSA time 0x%lx\n", hsa);
  356. csi_dev->hw.ipi3_hsa = hsa;
  357. return count;
  358. }
  359. static ssize_t ipi3_hsa_show(struct device *dev,
  360. struct device_attribute *attr,
  361. char *buf)
  362. {
  363. struct platform_device *pdev = to_platform_device(dev);
  364. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  365. struct dw_csi *csi_dev = &drvdata->csi_dev;
  366. char buffer[10];
  367. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hsa);
  368. return strlcpy(buf, buffer, PAGE_SIZE);
  369. }
  370. static ssize_t ipi3_hbp_store(struct device *dev,
  371. struct device_attribute *attr,
  372. const char *buf, size_t count)
  373. {
  374. int ret;
  375. unsigned long hbp;
  376. struct platform_device *pdev = to_platform_device(dev);
  377. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  378. struct dw_csi *csi_dev = &drvdata->csi_dev;
  379. ret = kstrtoul(buf, 16, &hbp);
  380. if (ret < 0)
  381. return ret;
  382. if (hbp > 0xFFF) {
  383. dev_err(dev, "Invalid HBP time %lx\n", hbp);
  384. return count;
  385. }
  386. dev_info(dev, "HBP time 0x%lx\n", hbp);
  387. csi_dev->hw.ipi3_hbp = hbp;
  388. return count;
  389. }
  390. static ssize_t ipi3_hbp_show(struct device *dev,
  391. struct device_attribute *attr,
  392. char *buf)
  393. {
  394. struct platform_device *pdev = to_platform_device(dev);
  395. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  396. struct dw_csi *csi_dev = &drvdata->csi_dev;
  397. char buffer[10];
  398. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hbp);
  399. return strlcpy(buf, buffer, PAGE_SIZE);
  400. }
  401. static ssize_t ipi3_hsd_store(struct device *dev,
  402. struct device_attribute *attr,
  403. const char *buf, size_t count)
  404. {
  405. int ret;
  406. unsigned long hsd;
  407. struct platform_device *pdev = to_platform_device(dev);
  408. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  409. struct dw_csi *csi_dev = &drvdata->csi_dev;
  410. ret = kstrtoul(buf, 16, &hsd);
  411. if (ret < 0)
  412. return ret;
  413. if (hsd > 0xFFF) {
  414. dev_err(dev, "Invalid HSD time %lx\n", hsd);
  415. return count;
  416. }
  417. dev_info(dev, "HSD time 0x%lx\n", hsd);
  418. csi_dev->hw.ipi3_hsd = hsd;
  419. return count;
  420. }
  421. static ssize_t ipi3_hsd_show(struct device *dev,
  422. struct device_attribute *attr,
  423. char *buf)
  424. {
  425. struct platform_device *pdev = to_platform_device(dev);
  426. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  427. struct dw_csi *csi_dev = &drvdata->csi_dev;
  428. char buffer[10];
  429. snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hsd);
  430. return strlcpy(buf, buffer, PAGE_SIZE);
  431. }
  432. static ssize_t vsa_store(struct device *dev,
  433. struct device_attribute *attr,
  434. const char *buf, size_t count)
  435. {
  436. int ret;
  437. unsigned long vsa;
  438. struct platform_device *pdev = to_platform_device(dev);
  439. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  440. struct dw_csi *csi_dev = &drvdata->csi_dev;
  441. ret = kstrtoul(buf, 16, &vsa);
  442. if (ret < 0)
  443. return ret;
  444. if (vsa > 0x3FF) {
  445. dev_err(dev, "Invalid VSA period %lx\n", vsa);
  446. return count;
  447. }
  448. dev_info(dev, "VSA period 0x%lx\n", vsa);
  449. csi_dev->hw.vsa = vsa;
  450. return count;
  451. }
  452. static ssize_t vsa_show(struct device *dev,
  453. struct device_attribute *attr,
  454. char *buf)
  455. {
  456. struct platform_device *pdev = to_platform_device(dev);
  457. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  458. struct dw_csi *csi_dev = &drvdata->csi_dev;
  459. char buffer[10];
  460. snprintf(buffer, 10, "%x\n", csi_dev->hw.vsa);
  461. return strlcpy(buf, buffer, PAGE_SIZE);
  462. }
  463. static ssize_t vbp_store(struct device *dev,
  464. struct device_attribute *attr,
  465. const char *buf, size_t count)
  466. {
  467. int ret;
  468. unsigned long vbp;
  469. struct platform_device *pdev = to_platform_device(dev);
  470. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  471. struct dw_csi *csi_dev = &drvdata->csi_dev;
  472. ret = kstrtoul(buf, 16, &vbp);
  473. if (ret < 0)
  474. return ret;
  475. if (vbp > 0x2FF) {
  476. dev_err(dev, "Invalid VBP period %lx\n", vbp);
  477. return count;
  478. }
  479. dev_info(dev, "VBP period 0x%lx\n", vbp);
  480. csi_dev->hw.vbp = vbp;
  481. return count;
  482. }
  483. static ssize_t vbp_show(struct device *dev,
  484. struct device_attribute *attr,
  485. char *buf)
  486. {
  487. struct platform_device *pdev = to_platform_device(dev);
  488. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  489. struct dw_csi *csi_dev = &drvdata->csi_dev;
  490. char buffer[10];
  491. snprintf(buffer, 10, "%x\n", csi_dev->hw.vbp);
  492. return strlcpy(buf, buffer, PAGE_SIZE);
  493. }
  494. static ssize_t vfp_store(struct device *dev,
  495. struct device_attribute *attr,
  496. const char *buf, size_t count)
  497. {
  498. int ret;
  499. unsigned long vfp;
  500. struct platform_device *pdev = to_platform_device(dev);
  501. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  502. struct dw_csi *csi_dev = &drvdata->csi_dev;
  503. ret = kstrtoul(buf, 16, &vfp);
  504. if (ret < 0)
  505. return ret;
  506. if (vfp > 0x3ff) {
  507. dev_err(dev, "Invalid VFP period %lx\n", vfp);
  508. return count;
  509. }
  510. dev_info(dev, "VFP period 0x%lx\n", vfp);
  511. csi_dev->hw.vfp = vfp;
  512. return count;
  513. }
  514. static ssize_t vfp_show(struct device *dev,
  515. struct device_attribute *attr,
  516. char *buf)
  517. {
  518. struct platform_device *pdev = to_platform_device(dev);
  519. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  520. struct dw_csi *csi_dev = &drvdata->csi_dev;
  521. char buffer[10];
  522. snprintf(buffer, 10, "%x\n", csi_dev->hw.vfp);
  523. return strlcpy(buf, buffer, PAGE_SIZE);
  524. }
  525. static ssize_t ipi_enable_mask_store(struct device *dev,
  526. struct device_attribute *attr,
  527. const char *buf, size_t count)
  528. {
  529. int ret;
  530. unsigned long enable_mask;
  531. struct platform_device *pdev = to_platform_device(dev);
  532. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  533. struct dw_csi *csi_dev = &drvdata->csi_dev;
  534. ret = kstrtoul(buf, 16, &enable_mask);
  535. if (ret < 0)
  536. return ret;
  537. dev_info(dev, "enable_mask 0x%lx\n", enable_mask);
  538. if (enable_mask & 1) {
  539. csi_dev->hw.ipi1_en = true;
  540. } else {
  541. csi_dev->hw.ipi1_en = false;
  542. }
  543. if (enable_mask & 2) {
  544. csi_dev->hw.ipi2_en = true;
  545. } else {
  546. csi_dev->hw.ipi2_en = false;
  547. }
  548. if (enable_mask & 4) {
  549. csi_dev->hw.ipi3_en = true;
  550. } else {
  551. csi_dev->hw.ipi3_en = false;
  552. }
  553. dw_mipi_csi_start(csi_dev);
  554. printk("enable mask is %lx\n", enable_mask);
  555. return count;
  556. }
  557. static ssize_t ipi_enable_mask_show(struct device *dev,
  558. struct device_attribute *attr,
  559. char *buf)
  560. {
  561. struct platform_device *pdev = to_platform_device(dev);
  562. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  563. struct dw_csi *csi_dev = &drvdata->csi_dev;
  564. char buffer[10];
  565. unsigned long enable_mask = 0;
  566. if (csi_dev->hw.ipi1_en == true) {
  567. enable_mask |= 1;
  568. }
  569. if (csi_dev->hw.ipi2_en == true) {
  570. enable_mask |= 2;
  571. }
  572. if (csi_dev->hw.ipi3_en == true) {
  573. enable_mask |= 4;
  574. }
  575. snprintf(buffer, 10, "%lx\n", enable_mask);
  576. return strlcpy(buf, buffer, PAGE_SIZE);
  577. }
  578. static ssize_t virtual_channel_store(struct device *dev,
  579. struct device_attribute *attr,
  580. const char *buf, size_t count)
  581. {
  582. int ret;
  583. unsigned long virtual_ch;
  584. struct platform_device *pdev = to_platform_device(dev);
  585. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  586. struct dw_csi *csi_dev = &drvdata->csi_dev;
  587. ret = kstrtoul(buf, 10, &virtual_ch);
  588. if (ret < 0)
  589. return ret;
  590. if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) {
  591. dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch);
  592. return count;
  593. }
  594. dev_info(dev, "Virtual Channel %lu\n", virtual_ch);
  595. csi_dev->hw.virtual_ch = virtual_ch;
  596. return count;
  597. }
  598. static ssize_t virtual_channel_show(struct device *dev,
  599. struct device_attribute *attr,
  600. char *buf)
  601. {
  602. struct platform_device *pdev = to_platform_device(dev);
  603. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  604. struct dw_csi *csi_dev = &drvdata->csi_dev;
  605. char buffer[10];
  606. snprintf(buffer, 10, "%d\n", csi_dev->hw.virtual_ch);
  607. return strlcpy(buf, buffer, PAGE_SIZE);
  608. }
  609. static ssize_t ipi2_virtual_channel_store(struct device *dev,
  610. struct device_attribute *attr,
  611. const char *buf, size_t count)
  612. {
  613. int ret;
  614. unsigned long virtual_ch;
  615. struct platform_device *pdev = to_platform_device(dev);
  616. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  617. struct dw_csi *csi_dev = &drvdata->csi_dev;
  618. ret = kstrtoul(buf, 10, &virtual_ch);
  619. if (ret < 0)
  620. return ret;
  621. if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) {
  622. dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch);
  623. return count;
  624. }
  625. dev_info(dev, "Virtual Channel %lu\n", virtual_ch);
  626. csi_dev->hw.ipi2_virtual_ch = virtual_ch;
  627. return count;
  628. }
  629. static ssize_t ipi2_virtual_channel_show(struct device *dev,
  630. struct device_attribute *attr,
  631. char *buf)
  632. {
  633. struct platform_device *pdev = to_platform_device(dev);
  634. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  635. struct dw_csi *csi_dev = &drvdata->csi_dev;
  636. char buffer[10];
  637. snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi2_virtual_ch);
  638. return strlcpy(buf, buffer, PAGE_SIZE);
  639. }
  640. static ssize_t ipi3_virtual_channel_store(struct device *dev,
  641. struct device_attribute *attr,
  642. const char *buf, size_t count)
  643. {
  644. int ret;
  645. unsigned long virtual_ch;
  646. struct platform_device *pdev = to_platform_device(dev);
  647. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  648. struct dw_csi *csi_dev = &drvdata->csi_dev;
  649. ret = kstrtoul(buf, 10, &virtual_ch);
  650. if (ret < 0)
  651. return ret;
  652. if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) {
  653. dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch);
  654. return count;
  655. }
  656. dev_info(dev, "Virtual Channel %lu\n", virtual_ch);
  657. csi_dev->hw.ipi3_virtual_ch = virtual_ch;
  658. return count;
  659. }
  660. static ssize_t ipi3_virtual_channel_show(struct device *dev,
  661. struct device_attribute *attr,
  662. char *buf)
  663. {
  664. struct platform_device *pdev = to_platform_device(dev);
  665. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  666. struct dw_csi *csi_dev = &drvdata->csi_dev;
  667. char buffer[10];
  668. snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi3_virtual_ch);
  669. return strlcpy(buf, buffer, PAGE_SIZE);
  670. }
  671. static ssize_t ipi_color_mode_store(struct device *dev,
  672. struct device_attribute *attr,
  673. const char *buf, size_t count)
  674. {
  675. int ret;
  676. unsigned long ipi_color_mode;
  677. struct platform_device *pdev = to_platform_device(dev);
  678. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  679. struct dw_csi *csi_dev = &drvdata->csi_dev;
  680. ret = kstrtoul(buf, 10, &ipi_color_mode);
  681. if (ret < 0)
  682. return ret;
  683. if ((signed int)ipi_color_mode < 0 || (signed int)ipi_color_mode > 1) {
  684. dev_err(dev,
  685. "Wrong Color Mode %lu, (48 bits -> 0 or 16 bits -> 1\n",
  686. ipi_color_mode);
  687. return count;
  688. }
  689. dev_info(dev, "IPI Color mode %lu\n", ipi_color_mode);
  690. csi_dev->hw.ipi_color_mode = ipi_color_mode;
  691. return count;
  692. }
  693. static ssize_t ipi_color_mode_show(struct device *dev,
  694. struct device_attribute *attr,
  695. char *buf)
  696. {
  697. struct platform_device *pdev = to_platform_device(dev);
  698. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  699. struct dw_csi *csi_dev = &drvdata->csi_dev;
  700. char buffer[10];
  701. snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_color_mode);
  702. return strlcpy(buf, buffer, PAGE_SIZE);
  703. }
  704. static ssize_t ipi_auto_flush_store(struct device *dev,
  705. struct device_attribute *attr,
  706. const char *buf, size_t count)
  707. {
  708. int ret;
  709. unsigned long ipi_auto_flush;
  710. struct platform_device *pdev = to_platform_device(dev);
  711. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  712. struct dw_csi *csi_dev = &drvdata->csi_dev;
  713. ret = kstrtoul(buf, 10, &ipi_auto_flush);
  714. if (ret < 0)
  715. return ret;
  716. if ((signed int)ipi_auto_flush < 0 || (signed int)ipi_auto_flush > 1) {
  717. dev_err(dev,
  718. "Invalid Auto Flush Mode %lu, (No -> 0 or Yes -> 1\n",
  719. ipi_auto_flush);
  720. return count;
  721. }
  722. dev_info(dev, "IPI Auto Flush %lu\n", ipi_auto_flush);
  723. csi_dev->hw.ipi_auto_flush = ipi_auto_flush;
  724. return count;
  725. }
  726. static ssize_t ipi_auto_flush_show(struct device *dev,
  727. struct device_attribute *attr,
  728. char *buf)
  729. {
  730. struct platform_device *pdev = to_platform_device(dev);
  731. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  732. struct dw_csi *csi_dev = &drvdata->csi_dev;
  733. char buffer[10];
  734. snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_auto_flush);
  735. return strlcpy(buf, buffer, PAGE_SIZE);
  736. }
  737. static ssize_t ipi_timings_mode_store(struct device *dev,
  738. struct device_attribute *attr,
  739. const char *buf, size_t count)
  740. {
  741. int ret;
  742. unsigned long ipi_mode;
  743. struct platform_device *pdev = to_platform_device(dev);
  744. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  745. struct dw_csi *csi_dev = &drvdata->csi_dev;
  746. ret = kstrtoul(buf, 10, &ipi_mode);
  747. if (ret < 0)
  748. return ret;
  749. if ((signed int)ipi_mode < 0 || (signed int)ipi_mode > 1) {
  750. dev_err(dev,
  751. "Invalid Timing Source %lu (Camera:0|Controller:1)\n",
  752. ipi_mode);
  753. return count;
  754. }
  755. dev_info(dev, "IPI Color mode %lu\n", ipi_mode);
  756. csi_dev->hw.ipi_mode = ipi_mode;
  757. return count;
  758. }
  759. static ssize_t ipi_timings_mode_show(struct device *dev,
  760. struct device_attribute *attr,
  761. char *buf)
  762. {
  763. struct platform_device *pdev = to_platform_device(dev);
  764. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  765. struct dw_csi *csi_dev = &drvdata->csi_dev;
  766. char buffer[10];
  767. snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_mode);
  768. return strlcpy(buf, buffer, PAGE_SIZE);
  769. }
  770. static ssize_t output_type_store(struct device *dev,
  771. struct device_attribute *attr,
  772. const char *buf, size_t count)
  773. {
  774. int ret;
  775. unsigned long output;
  776. struct platform_device *pdev = to_platform_device(dev);
  777. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  778. struct dw_csi *csi_dev = &drvdata->csi_dev;
  779. ret = kstrtoul(buf, 10, &output);
  780. if (ret < 0)
  781. return ret;
  782. if ((signed int)output < 0 || (signed int)output > 1) {
  783. dev_err(dev,
  784. "Invalid Core output %lu to be used \
  785. (IPI-> 0 or IDI->1 or BOTH- 2\n",
  786. output);
  787. return count;
  788. }
  789. dev_info(dev, "IPI Color mode %lu\n", output);
  790. csi_dev->hw.output = output;
  791. return count;
  792. }
  793. static ssize_t output_type_show(struct device *dev,
  794. struct device_attribute *attr,
  795. char *buf)
  796. {
  797. struct platform_device *pdev = to_platform_device(dev);
  798. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  799. struct dw_csi *csi_dev = &drvdata->csi_dev;
  800. char buffer[10];
  801. snprintf(buffer, 10, "%d\n", csi_dev->hw.output);
  802. return strlcpy(buf, buffer, PAGE_SIZE);
  803. }
  804. static ssize_t csi_power_store(struct device *dev,
  805. struct device_attribute *attr,
  806. const char *buf, size_t count)
  807. {
  808. int ret;
  809. unsigned long on;
  810. struct platform_device *pdev = to_platform_device(dev);
  811. struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev);
  812. struct dw_csi *csi_dev = &drvdata->csi_dev;
  813. ret = kstrtoul(buf, 10, &on);
  814. if (ret < 0)
  815. return ret;
  816. dw_mipi_csi_s_power(csi_dev, on);
  817. printk("csi set power: %lu\n", on);
  818. return count;
  819. }
  820. static DEVICE_ATTR_RO(core_version);
  821. static DEVICE_ATTR_RO(core_reset);
  822. static DEVICE_ATTR_RW(n_lanes);
  823. static DEVICE_ATTR_RW(width);
  824. static DEVICE_ATTR_RW(height);
  825. static DEVICE_ATTR_RW(data_type);
  826. static DEVICE_ATTR_RW(hsa);
  827. static DEVICE_ATTR_RW(hbp);
  828. static DEVICE_ATTR_RW(hsd);
  829. static DEVICE_ATTR_RW(vsa);
  830. static DEVICE_ATTR_RW(vbp);
  831. static DEVICE_ATTR_RW(vfp);
  832. static DEVICE_ATTR_RW(virtual_channel);
  833. static DEVICE_ATTR_RW(ipi_color_mode);
  834. static DEVICE_ATTR_RW(ipi_auto_flush);
  835. static DEVICE_ATTR_RW(ipi_timings_mode);
  836. static DEVICE_ATTR_RW(output_type);
  837. static DEVICE_ATTR_WO(csi_power);
  838. static DEVICE_ATTR_RW(ipi2_virtual_channel);
  839. static DEVICE_ATTR_RW(ipi3_virtual_channel);
  840. static DEVICE_ATTR_RW(ipi_enable_mask);
  841. static DEVICE_ATTR_RW(ipi2_hsa);
  842. static DEVICE_ATTR_RW(ipi2_hbp);
  843. static DEVICE_ATTR_RW(ipi2_hsd);
  844. static DEVICE_ATTR_RW(ipi3_hsa);
  845. static DEVICE_ATTR_RW(ipi3_hbp);
  846. static DEVICE_ATTR_RW(ipi3_hsd);
  847. int dw_csi_create_capabilities_sysfs(struct platform_device *pdev)
  848. {
  849. device_create_file(&pdev->dev, &dev_attr_core_version);
  850. device_create_file(&pdev->dev, &dev_attr_core_reset);
  851. device_create_file(&pdev->dev, &dev_attr_n_lanes);
  852. device_create_file(&pdev->dev, &dev_attr_height);
  853. device_create_file(&pdev->dev, &dev_attr_width);
  854. device_create_file(&pdev->dev, &dev_attr_data_type);
  855. device_create_file(&pdev->dev, &dev_attr_hsa);
  856. device_create_file(&pdev->dev, &dev_attr_hbp);
  857. device_create_file(&pdev->dev, &dev_attr_hsd);
  858. device_create_file(&pdev->dev, &dev_attr_vsa);
  859. device_create_file(&pdev->dev, &dev_attr_vbp);
  860. device_create_file(&pdev->dev, &dev_attr_vfp);
  861. device_create_file(&pdev->dev, &dev_attr_virtual_channel);
  862. device_create_file(&pdev->dev, &dev_attr_ipi_color_mode);
  863. device_create_file(&pdev->dev, &dev_attr_ipi_auto_flush);
  864. device_create_file(&pdev->dev, &dev_attr_ipi_timings_mode);
  865. device_create_file(&pdev->dev, &dev_attr_output_type);
  866. device_create_file(&pdev->dev, &dev_attr_csi_power);
  867. device_create_file(&pdev->dev, &dev_attr_ipi2_virtual_channel);
  868. device_create_file(&pdev->dev, &dev_attr_ipi3_virtual_channel);
  869. device_create_file(&pdev->dev, &dev_attr_ipi_enable_mask);
  870. device_create_file(&pdev->dev, &dev_attr_ipi2_hsa);
  871. device_create_file(&pdev->dev, &dev_attr_ipi2_hbp);
  872. device_create_file(&pdev->dev, &dev_attr_ipi2_hsd);
  873. device_create_file(&pdev->dev, &dev_attr_ipi3_hsa);
  874. device_create_file(&pdev->dev, &dev_attr_ipi3_hbp);
  875. device_create_file(&pdev->dev, &dev_attr_ipi3_hsd);
  876. return 0;
  877. }
  878. int dw_csi_remove_capabilities_sysfs(struct platform_device *pdev)
  879. {
  880. device_remove_file(&pdev->dev, &dev_attr_core_version);
  881. device_remove_file(&pdev->dev, &dev_attr_core_reset);
  882. device_remove_file(&pdev->dev, &dev_attr_n_lanes);
  883. device_remove_file(&pdev->dev, &dev_attr_height);
  884. device_remove_file(&pdev->dev, &dev_attr_width);
  885. device_remove_file(&pdev->dev, &dev_attr_data_type);
  886. device_remove_file(&pdev->dev, &dev_attr_hsa);
  887. device_remove_file(&pdev->dev, &dev_attr_hbp);
  888. device_remove_file(&pdev->dev, &dev_attr_hsd);
  889. device_remove_file(&pdev->dev, &dev_attr_vsa);
  890. device_remove_file(&pdev->dev, &dev_attr_vbp);
  891. device_remove_file(&pdev->dev, &dev_attr_vfp);
  892. device_remove_file(&pdev->dev, &dev_attr_virtual_channel);
  893. device_remove_file(&pdev->dev, &dev_attr_ipi_color_mode);
  894. device_remove_file(&pdev->dev, &dev_attr_ipi_auto_flush);
  895. device_remove_file(&pdev->dev, &dev_attr_ipi_timings_mode);
  896. device_remove_file(&pdev->dev, &dev_attr_output_type);
  897. device_remove_file(&pdev->dev, &dev_attr_csi_power);
  898. device_remove_file(&pdev->dev, &dev_attr_ipi2_virtual_channel);
  899. device_remove_file(&pdev->dev, &dev_attr_ipi3_virtual_channel);
  900. device_remove_file(&pdev->dev, &dev_attr_ipi_enable_mask);
  901. device_remove_file(&pdev->dev, &dev_attr_ipi2_hsa);
  902. device_remove_file(&pdev->dev, &dev_attr_ipi2_hbp);
  903. device_remove_file(&pdev->dev, &dev_attr_ipi2_hsd);
  904. device_remove_file(&pdev->dev, &dev_attr_ipi3_hsa);
  905. device_remove_file(&pdev->dev, &dev_attr_ipi3_hbp);
  906. device_remove_file(&pdev->dev, &dev_attr_ipi3_hsd);
  907. return 0;
  908. }