0012-cameras.patch 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. From f92f43e71ed359c927a7ac957a0e91fbd67bc373 Mon Sep 17 00:00:00 2001
  2. From: Hans de Goede <hdegoede@redhat.com>
  3. Date: Sun, 10 Oct 2021 20:56:57 +0200
  4. Subject: [PATCH] ACPI: delay enumeration of devices with a _DEP pointing to an
  5. INT3472 device
  6. The clk and regulator frameworks expect clk/regulator consumer-devices
  7. to have info about the consumed clks/regulators described in the device's
  8. fw_node.
  9. To work around cases where this info is not present in the firmware tables,
  10. which is often the case on x86/ACPI devices, both frameworks allow the
  11. provider-driver to attach info about consumers to the clks/regulators
  12. when registering these.
  13. This causes problems with the probe ordering wrt drivers for consumers
  14. of these clks/regulators. Since the lookups are only registered when the
  15. provider-driver binds, trying to get these clks/regulators before then
  16. results in a -ENOENT error for clks and a dummy regulator for regulators.
  17. One case where we hit this issue is camera sensors such as e.g. the OV8865
  18. sensor found on the Microsoft Surface Go. The sensor uses clks, regulators
  19. and GPIOs provided by a TPS68470 PMIC which is described in an INT3472
  20. ACPI device. There is special platform code handling this and setting
  21. platform_data with the necessary consumer info on the MFD cells
  22. instantiated for the PMIC under: drivers/platform/x86/intel/int3472.
  23. For this to work properly the ov8865 driver must not bind to the I2C-client
  24. for the OV8865 sensor until after the TPS68470 PMIC gpio, regulator and
  25. clk MFD cells have all been fully setup.
  26. The OV8865 on the Microsoft Surface Go is just one example, all X86
  27. devices using the Intel IPU3 camera block found on recent Intel SoCs
  28. have similar issues where there is an INT3472 HID ACPI-device, which
  29. describes the clks and regulators, and the driver for this INT3472 device
  30. must be fully initialized before the sensor driver (any sensor driver)
  31. binds for things to work properly.
  32. On these devices the ACPI nodes describing the sensors all have a _DEP
  33. dependency on the matching INT3472 ACPI device (there is one per sensor).
  34. This allows solving the probe-ordering problem by delaying the enumeration
  35. (instantiation of the I2C-client in the ov8865 example) of ACPI-devices
  36. which have a _DEP dependency on an INT3472 device.
  37. The new acpi_dev_ready_for_enumeration() helper used for this is also
  38. exported because for devices, which have the enumeration_by_parent flag
  39. set, the parent-driver will do its own scan of child ACPI devices and
  40. it will try to enumerate those during its probe(). Code doing this such
  41. as e.g. the i2c-core-acpi.c code must call this new helper to ensure
  42. that it too delays the enumeration until all the _DEP dependencies are
  43. met on devices which have the new honor_deps flag set.
  44. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  45. Patchset: cameras
  46. ---
  47. drivers/acpi/scan.c | 3 +++
  48. 1 file changed, 3 insertions(+)
  49. diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
  50. index 0c6f06abe3f4..4fc320f424e8 100644
  51. --- a/drivers/acpi/scan.c
  52. +++ b/drivers/acpi/scan.c
  53. @@ -2106,6 +2106,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
  54. static void acpi_default_enumeration(struct acpi_device *device)
  55. {
  56. + if (!acpi_dev_ready_for_enumeration(device))
  57. + return;
  58. +
  59. /*
  60. * Do not enumerate devices with enumeration_by_parent flag set as
  61. * they will be enumerated by their respective parents.
  62. --
  63. 2.41.0
  64. From 3c62c3082ba3511bec8140c90a22af1599c63d7c Mon Sep 17 00:00:00 2001
  65. From: zouxiaoh <xiaohong.zou@intel.com>
  66. Date: Fri, 25 Jun 2021 08:52:59 +0800
  67. Subject: [PATCH] iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs
  68. Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
  69. The IPU driver allocates its own page table that is not mapped
  70. via the DMA, and thus the Intel IOMMU driver blocks access giving
  71. this error: DMAR: DRHD: handling fault status reg 3 DMAR:
  72. [DMA Read] Request device [00:05.0] PASID ffffffff
  73. fault addr 76406000 [fault reason 06] PTE Read access is not set
  74. As IPU is not an external facing device which is not risky, so use
  75. IOMMU passthrough mode for Intel IPUs.
  76. Change-Id: I6dcccdadac308cf42e20a18e1b593381391e3e6b
  77. Depends-On: Iacd67578e8c6a9b9ac73285f52b4081b72fb68a6
  78. Tracked-On: #JIITL8-411
  79. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
  80. Signed-off-by: zouxiaoh <xiaohong.zou@intel.com>
  81. Signed-off-by: Xu Chongyang <chongyang.xu@intel.com>
  82. Patchset: cameras
  83. ---
  84. drivers/iommu/intel/iommu.c | 30 ++++++++++++++++++++++++++++++
  85. 1 file changed, 30 insertions(+)
  86. diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
  87. index 3ebd2260cdab..f8937235de4b 100644
  88. --- a/drivers/iommu/intel/iommu.c
  89. +++ b/drivers/iommu/intel/iommu.c
  90. @@ -37,6 +37,12 @@
  91. #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
  92. #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
  93. #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
  94. +#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \
  95. + ((pdev)->device == 0x9a19 || \
  96. + (pdev)->device == 0x9a39 || \
  97. + (pdev)->device == 0x4e19 || \
  98. + (pdev)->device == 0x465d || \
  99. + (pdev)->device == 0x1919))
  100. #define IS_IPTS(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \
  101. ((pdev)->device == 0x9d3e))
  102. #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
  103. @@ -290,12 +296,14 @@ EXPORT_SYMBOL_GPL(intel_iommu_enabled);
  104. static int dmar_map_gfx = 1;
  105. static int dmar_map_ipts = 1;
  106. +static int dmar_map_ipu = 1;
  107. static int intel_iommu_superpage = 1;
  108. static int iommu_identity_mapping;
  109. static int iommu_skip_te_disable;
  110. #define IDENTMAP_GFX 2
  111. #define IDENTMAP_AZALIA 4
  112. +#define IDENTMAP_IPU 8
  113. #define IDENTMAP_IPTS 16
  114. const struct iommu_ops intel_iommu_ops;
  115. @@ -2593,6 +2601,9 @@ static int device_def_domain_type(struct device *dev)
  116. if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
  117. return IOMMU_DOMAIN_IDENTITY;
  118. + if ((iommu_identity_mapping & IDENTMAP_IPU) && IS_INTEL_IPU(pdev))
  119. + return IOMMU_DOMAIN_IDENTITY;
  120. +
  121. if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev))
  122. return IOMMU_DOMAIN_IDENTITY;
  123. }
  124. @@ -2984,6 +2995,9 @@ static int __init init_dmars(void)
  125. if (!dmar_map_gfx)
  126. iommu_identity_mapping |= IDENTMAP_GFX;
  127. + if (!dmar_map_ipu)
  128. + iommu_identity_mapping |= IDENTMAP_IPU;
  129. +
  130. if (!dmar_map_ipts)
  131. iommu_identity_mapping |= IDENTMAP_IPTS;
  132. @@ -4829,6 +4843,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
  133. dmar_map_gfx = 0;
  134. }
  135. +static void quirk_iommu_ipu(struct pci_dev *dev)
  136. +{
  137. + if (!IS_INTEL_IPU(dev))
  138. + return;
  139. +
  140. + if (risky_device(dev))
  141. + return;
  142. +
  143. + pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n");
  144. + dmar_map_ipu = 0;
  145. +}
  146. +
  147. static void quirk_iommu_ipts(struct pci_dev *dev)
  148. {
  149. if (!IS_IPTS(dev))
  150. @@ -4840,6 +4866,7 @@ static void quirk_iommu_ipts(struct pci_dev *dev)
  151. pci_info(dev, "Passthrough IOMMU for IPTS\n");
  152. dmar_map_ipts = 0;
  153. }
  154. +
  155. /* G4x/GM45 integrated gfx dmar support is totally busted. */
  156. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
  157. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
  158. @@ -4875,6 +4902,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
  159. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
  160. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
  161. +/* disable IPU dmar support */
  162. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu);
  163. +
  164. /* disable IPTS dmar support */
  165. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9D3E, quirk_iommu_ipts);
  166. --
  167. 2.41.0
  168. From 1fb78ef3166b41c3ab5d20ed351979f55ef6e219 Mon Sep 17 00:00:00 2001
  169. From: Daniel Scally <djrscally@gmail.com>
  170. Date: Sun, 10 Oct 2021 20:57:02 +0200
  171. Subject: [PATCH] platform/x86: int3472: Enable I2c daisy chain
  172. The TPS68470 PMIC has an I2C passthrough mode through which I2C traffic
  173. can be forwarded to a device connected to the PMIC as though it were
  174. connected directly to the system bus. Enable this mode when the chip
  175. is initialised.
  176. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  177. Patchset: cameras
  178. ---
  179. drivers/platform/x86/intel/int3472/tps68470.c | 7 +++++++
  180. 1 file changed, 7 insertions(+)
  181. diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
  182. index 5b8d1a9620a5..6a0ff035cf20 100644
  183. --- a/drivers/platform/x86/intel/int3472/tps68470.c
  184. +++ b/drivers/platform/x86/intel/int3472/tps68470.c
  185. @@ -46,6 +46,13 @@ static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
  186. return ret;
  187. }
  188. + /* Enable I2C daisy chain */
  189. + ret = regmap_write(regmap, TPS68470_REG_S_I2C_CTL, 0x03);
  190. + if (ret) {
  191. + dev_err(dev, "Failed to enable i2c daisy chain\n");
  192. + return ret;
  193. + }
  194. +
  195. dev_info(dev, "TPS68470 REVID: 0x%02x\n", version);
  196. return 0;
  197. --
  198. 2.41.0
  199. From 05b3accaa005941fb2fd627aa99c337e13a76c57 Mon Sep 17 00:00:00 2001
  200. From: Daniel Scally <djrscally@gmail.com>
  201. Date: Wed, 4 May 2022 23:21:45 +0100
  202. Subject: [PATCH] media: ipu3-cio2: Move functionality from .complete() to
  203. .bound()
  204. Creating links and registering subdev nodes during the .complete()
  205. callback has the unfortunate effect of preventing all cameras that
  206. connect to a notifier from working if any one of their drivers fails
  207. to probe. Moving the functionality from .complete() to .bound() allows
  208. those camera sensor drivers that did probe correctly to work regardless.
  209. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  210. Patchset: cameras
  211. ---
  212. drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 65 +++++++------------
  213. 1 file changed, 23 insertions(+), 42 deletions(-)
  214. diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  215. index 3b76a9d0383a..38f9f4da1922 100644
  216. --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  217. +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  218. @@ -1383,7 +1383,10 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier,
  219. {
  220. struct cio2_device *cio2 = to_cio2_device(notifier);
  221. struct sensor_async_subdev *s_asd = to_sensor_asd(asd);
  222. + struct device *dev = &cio2->pci_dev->dev;
  223. struct cio2_queue *q;
  224. + unsigned int pad;
  225. + int ret;
  226. if (cio2->queue[s_asd->csi2.port].sensor)
  227. return -EBUSY;
  228. @@ -1394,7 +1397,26 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier,
  229. q->sensor = sd;
  230. q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port);
  231. - return 0;
  232. + for (pad = 0; pad < q->sensor->entity.num_pads; pad++)
  233. + if (q->sensor->entity.pads[pad].flags &
  234. + MEDIA_PAD_FL_SOURCE)
  235. + break;
  236. +
  237. + if (pad == q->sensor->entity.num_pads) {
  238. + dev_err(dev, "failed to find src pad for %s\n",
  239. + q->sensor->name);
  240. + return -ENXIO;
  241. + }
  242. +
  243. + ret = media_create_pad_link(&q->sensor->entity, pad, &q->subdev.entity,
  244. + CIO2_PAD_SINK, 0);
  245. + if (ret) {
  246. + dev_err(dev, "failed to create link for %s\n",
  247. + q->sensor->name);
  248. + return ret;
  249. + }
  250. +
  251. + return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
  252. }
  253. /* The .unbind callback */
  254. @@ -1408,50 +1430,9 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
  255. cio2->queue[s_asd->csi2.port].sensor = NULL;
  256. }
  257. -/* .complete() is called after all subdevices have been located */
  258. -static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
  259. -{
  260. - struct cio2_device *cio2 = to_cio2_device(notifier);
  261. - struct device *dev = &cio2->pci_dev->dev;
  262. - struct sensor_async_subdev *s_asd;
  263. - struct v4l2_async_subdev *asd;
  264. - struct cio2_queue *q;
  265. - unsigned int pad;
  266. - int ret;
  267. -
  268. - list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) {
  269. - s_asd = to_sensor_asd(asd);
  270. - q = &cio2->queue[s_asd->csi2.port];
  271. -
  272. - for (pad = 0; pad < q->sensor->entity.num_pads; pad++)
  273. - if (q->sensor->entity.pads[pad].flags &
  274. - MEDIA_PAD_FL_SOURCE)
  275. - break;
  276. -
  277. - if (pad == q->sensor->entity.num_pads) {
  278. - dev_err(dev, "failed to find src pad for %s\n",
  279. - q->sensor->name);
  280. - return -ENXIO;
  281. - }
  282. -
  283. - ret = media_create_pad_link(
  284. - &q->sensor->entity, pad,
  285. - &q->subdev.entity, CIO2_PAD_SINK,
  286. - 0);
  287. - if (ret) {
  288. - dev_err(dev, "failed to create link for %s\n",
  289. - q->sensor->name);
  290. - return ret;
  291. - }
  292. - }
  293. -
  294. - return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
  295. -}
  296. -
  297. static const struct v4l2_async_notifier_operations cio2_async_ops = {
  298. .bound = cio2_notifier_bound,
  299. .unbind = cio2_notifier_unbind,
  300. - .complete = cio2_notifier_complete,
  301. };
  302. static int cio2_parse_firmware(struct cio2_device *cio2)
  303. --
  304. 2.41.0
  305. From 9315febe453d4d0f55cd2049aec9bcc4d56a78ec Mon Sep 17 00:00:00 2001
  306. From: Daniel Scally <djrscally@gmail.com>
  307. Date: Thu, 2 Jun 2022 22:15:56 +0100
  308. Subject: [PATCH] media: ipu3-cio2: Re-add .complete() to ipu3-cio2
  309. Removing the .complete() callback had some unintended consequences.
  310. Because the VCM driver is not directly linked to the ipu3-cio2
  311. driver .bound() never gets called for it, which means its devnode
  312. is never created if it probes late. Because .complete() waits for
  313. any sub-notifiers to also be complete it is captured in that call.
  314. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  315. Patchset: cameras
  316. ---
  317. drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 9 +++++++++
  318. 1 file changed, 9 insertions(+)
  319. diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  320. index 38f9f4da1922..82681df7d794 100644
  321. --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  322. +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  323. @@ -1430,9 +1430,18 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
  324. cio2->queue[s_asd->csi2.port].sensor = NULL;
  325. }
  326. +/* .complete() is called after all subdevices have been located */
  327. +static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
  328. +{
  329. + struct cio2_device *cio2 = to_cio2_device(notifier);
  330. +
  331. + return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
  332. +}
  333. +
  334. static const struct v4l2_async_notifier_operations cio2_async_ops = {
  335. .bound = cio2_notifier_bound,
  336. .unbind = cio2_notifier_unbind,
  337. + .complete = cio2_notifier_complete,
  338. };
  339. static int cio2_parse_firmware(struct cio2_device *cio2)
  340. --
  341. 2.41.0
  342. From 2e073b3e4c885307eb69205b5a8f4e27c57e7811 Mon Sep 17 00:00:00 2001
  343. From: Daniel Scally <djrscally@gmail.com>
  344. Date: Thu, 28 Oct 2021 21:55:16 +0100
  345. Subject: [PATCH] media: i2c: Add driver for DW9719 VCM
  346. Add a driver for the DW9719 VCM. The driver creates a v4l2 subdevice
  347. and registers a control to set the desired focus.
  348. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  349. Patchset: cameras
  350. ---
  351. MAINTAINERS | 7 +
  352. drivers/media/i2c/Kconfig | 11 +
  353. drivers/media/i2c/Makefile | 1 +
  354. drivers/media/i2c/dw9719.c | 425 +++++++++++++++++++++++++++++++++++++
  355. 4 files changed, 444 insertions(+)
  356. create mode 100644 drivers/media/i2c/dw9719.c
  357. diff --git a/MAINTAINERS b/MAINTAINERS
  358. index c6545eb54104..a197e0a54eed 100644
  359. --- a/MAINTAINERS
  360. +++ b/MAINTAINERS
  361. @@ -6237,6 +6237,13 @@ T: git git://linuxtv.org/media_tree.git
  362. F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml
  363. F: drivers/media/i2c/dw9714.c
  364. +DONGWOON DW9719 LENS VOICE COIL DRIVER
  365. +M: Daniel Scally <djrscally@gmail.com>
  366. +L: linux-media@vger.kernel.org
  367. +S: Maintained
  368. +T: git git://linuxtv.org/media_tree.git
  369. +F: drivers/media/i2c/dw9719.c
  370. +
  371. DONGWOON DW9768 LENS VOICE COIL DRIVER
  372. M: Dongchun Zhu <dongchun.zhu@mediatek.com>
  373. L: linux-media@vger.kernel.org
  374. diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
  375. index c3d5952ca27e..e759470a0b6b 100644
  376. --- a/drivers/media/i2c/Kconfig
  377. +++ b/drivers/media/i2c/Kconfig
  378. @@ -887,6 +887,17 @@ config VIDEO_DW9714
  379. capability. This is designed for linear control of
  380. voice coil motors, controlled via I2C serial interface.
  381. +config VIDEO_DW9719
  382. + tristate "DW9719 lens voice coil support"
  383. + depends on I2C && VIDEO_V4L2
  384. + select MEDIA_CONTROLLER
  385. + select VIDEO_V4L2_SUBDEV_API
  386. + select V4L2_ASYNC
  387. + help
  388. + This is a driver for the DW9719 camera lens voice coil.
  389. + This is designed for linear control of voice coil motors,
  390. + controlled via I2C serial interface.
  391. +
  392. config VIDEO_DW9768
  393. tristate "DW9768 lens voice coil support"
  394. depends on I2C && VIDEO_DEV
  395. diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
  396. index 4f5e9d9cee85..eef3ee84d7dc 100644
  397. --- a/drivers/media/i2c/Makefile
  398. +++ b/drivers/media/i2c/Makefile
  399. @@ -30,6 +30,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
  400. obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
  401. obj-$(CONFIG_VIDEO_CX25840) += cx25840/
  402. obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
  403. +obj-$(CONFIG_VIDEO_DW9719) += dw9719.o
  404. obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
  405. obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
  406. obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
  407. diff --git a/drivers/media/i2c/dw9719.c b/drivers/media/i2c/dw9719.c
  408. new file mode 100644
  409. index 000000000000..180b04d2a6b3
  410. --- /dev/null
  411. +++ b/drivers/media/i2c/dw9719.c
  412. @@ -0,0 +1,425 @@
  413. +// SPDX-License-Identifier: GPL-2.0
  414. +// Copyright (c) 2012 Intel Corporation
  415. +
  416. +/*
  417. + * Based on linux/modules/camera/drivers/media/i2c/imx/dw9719.c in this repo:
  418. + * https://github.com/ZenfoneArea/android_kernel_asus_zenfone5
  419. + */
  420. +
  421. +#include <asm/unaligned.h>
  422. +
  423. +#include <linux/delay.h>
  424. +#include <linux/i2c.h>
  425. +#include <linux/pm_runtime.h>
  426. +#include <linux/regulator/consumer.h>
  427. +#include <linux/types.h>
  428. +
  429. +#include <media/v4l2-common.h>
  430. +#include <media/v4l2-ctrls.h>
  431. +#include <media/v4l2-subdev.h>
  432. +
  433. +#define DW9719_MAX_FOCUS_POS 1023
  434. +#define DW9719_CTRL_STEPS 16
  435. +#define DW9719_CTRL_DELAY_US 1000
  436. +#define DELAY_MAX_PER_STEP_NS (1000000 * 1023)
  437. +
  438. +#define DW9719_INFO 0
  439. +#define DW9719_ID 0xF1
  440. +#define DW9719_CONTROL 2
  441. +#define DW9719_VCM_CURRENT 3
  442. +
  443. +#define DW9719_MODE 6
  444. +#define DW9719_VCM_FREQ 7
  445. +
  446. +#define DW9719_MODE_SAC3 0x40
  447. +#define DW9719_DEFAULT_VCM_FREQ 0x60
  448. +#define DW9719_ENABLE_RINGING 0x02
  449. +
  450. +#define NUM_REGULATORS 2
  451. +
  452. +#define to_dw9719_device(x) container_of(x, struct dw9719_device, sd)
  453. +
  454. +struct dw9719_device {
  455. + struct device *dev;
  456. + struct i2c_client *client;
  457. + struct regulator_bulk_data regulators[NUM_REGULATORS];
  458. + struct v4l2_subdev sd;
  459. +
  460. + struct dw9719_v4l2_ctrls {
  461. + struct v4l2_ctrl_handler handler;
  462. + struct v4l2_ctrl *focus;
  463. + } ctrls;
  464. +};
  465. +
  466. +static int dw9719_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val)
  467. +{
  468. + struct i2c_msg msg[2];
  469. + u8 buf[2] = { reg };
  470. + int ret;
  471. +
  472. + msg[0].addr = client->addr;
  473. + msg[0].flags = 0;
  474. + msg[0].len = 1;
  475. + msg[0].buf = buf;
  476. +
  477. + msg[1].addr = client->addr;
  478. + msg[1].flags = I2C_M_RD;
  479. + msg[1].len = 1;
  480. + msg[1].buf = &buf[1];
  481. + *val = 0;
  482. +
  483. + ret = i2c_transfer(client->adapter, msg, 2);
  484. + if (ret < 0)
  485. + return ret;
  486. +
  487. + *val = buf[1];
  488. +
  489. + return 0;
  490. +}
  491. +
  492. +static int dw9719_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
  493. +{
  494. + struct i2c_msg msg;
  495. + int ret;
  496. +
  497. + u8 buf[2] = { reg, val };
  498. +
  499. + msg.addr = client->addr;
  500. + msg.flags = 0;
  501. + msg.len = sizeof(buf);
  502. + msg.buf = buf;
  503. +
  504. + ret = i2c_transfer(client->adapter, &msg, 1);
  505. +
  506. + return ret < 0 ? ret : 0;
  507. +}
  508. +
  509. +static int dw9719_i2c_wr16(struct i2c_client *client, u8 reg, u16 val)
  510. +{
  511. + struct i2c_msg msg;
  512. + u8 buf[3] = { reg };
  513. + int ret;
  514. +
  515. + put_unaligned_be16(val, buf + 1);
  516. +
  517. + msg.addr = client->addr;
  518. + msg.flags = 0;
  519. + msg.len = sizeof(buf);
  520. + msg.buf = buf;
  521. +
  522. + ret = i2c_transfer(client->adapter, &msg, 1);
  523. +
  524. + return ret < 0 ? ret : 0;
  525. +}
  526. +
  527. +static int dw9719_detect(struct dw9719_device *dw9719)
  528. +{
  529. + int ret;
  530. + u8 val;
  531. +
  532. + ret = dw9719_i2c_rd8(dw9719->client, DW9719_INFO, &val);
  533. + if (ret < 0)
  534. + return ret;
  535. +
  536. + if (val != DW9719_ID) {
  537. + dev_err(dw9719->dev, "Failed to detect correct id\n");
  538. + ret = -ENXIO;
  539. + }
  540. +
  541. + return 0;
  542. +}
  543. +
  544. +static int dw9719_power_down(struct dw9719_device *dw9719)
  545. +{
  546. + return regulator_bulk_disable(NUM_REGULATORS, dw9719->regulators);
  547. +}
  548. +
  549. +static int dw9719_power_up(struct dw9719_device *dw9719)
  550. +{
  551. + int ret;
  552. +
  553. + ret = regulator_bulk_enable(NUM_REGULATORS, dw9719->regulators);
  554. + if (ret)
  555. + return ret;
  556. +
  557. + /* Jiggle SCL pin to wake up device */
  558. + ret = dw9719_i2c_wr8(dw9719->client, DW9719_CONTROL, 1);
  559. +
  560. + /* Need 100us to transit from SHUTDOWN to STANDBY*/
  561. + usleep_range(100, 1000);
  562. +
  563. + ret = dw9719_i2c_wr8(dw9719->client, DW9719_CONTROL,
  564. + DW9719_ENABLE_RINGING);
  565. + if (ret < 0)
  566. + goto fail_powerdown;
  567. +
  568. + ret = dw9719_i2c_wr8(dw9719->client, DW9719_MODE, DW9719_MODE_SAC3);
  569. + if (ret < 0)
  570. + goto fail_powerdown;
  571. +
  572. + ret = dw9719_i2c_wr8(dw9719->client, DW9719_VCM_FREQ,
  573. + DW9719_DEFAULT_VCM_FREQ);
  574. + if (ret < 0)
  575. + goto fail_powerdown;
  576. +
  577. + return 0;
  578. +
  579. +fail_powerdown:
  580. + dw9719_power_down(dw9719);
  581. + return ret;
  582. +}
  583. +
  584. +static int dw9719_t_focus_abs(struct dw9719_device *dw9719, s32 value)
  585. +{
  586. + int ret;
  587. +
  588. + value = clamp(value, 0, DW9719_MAX_FOCUS_POS);
  589. + ret = dw9719_i2c_wr16(dw9719->client, DW9719_VCM_CURRENT, value);
  590. + if (ret < 0)
  591. + return ret;
  592. +
  593. + return 0;
  594. +}
  595. +
  596. +static int dw9719_set_ctrl(struct v4l2_ctrl *ctrl)
  597. +{
  598. + struct dw9719_device *dw9719 = container_of(ctrl->handler,
  599. + struct dw9719_device,
  600. + ctrls.handler);
  601. + int ret;
  602. +
  603. + /* Only apply changes to the controls if the device is powered up */
  604. + if (!pm_runtime_get_if_in_use(dw9719->dev))
  605. + return 0;
  606. +
  607. + switch (ctrl->id) {
  608. + case V4L2_CID_FOCUS_ABSOLUTE:
  609. + ret = dw9719_t_focus_abs(dw9719, ctrl->val);
  610. + break;
  611. + default:
  612. + ret = -EINVAL;
  613. + }
  614. +
  615. + pm_runtime_put(dw9719->dev);
  616. +
  617. + return ret;
  618. +}
  619. +
  620. +static const struct v4l2_ctrl_ops dw9719_ctrl_ops = {
  621. + .s_ctrl = dw9719_set_ctrl,
  622. +};
  623. +
  624. +static int __maybe_unused dw9719_suspend(struct device *dev)
  625. +{
  626. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  627. + struct dw9719_device *dw9719 = to_dw9719_device(sd);
  628. + int ret;
  629. + int val;
  630. +
  631. + for (val = dw9719->ctrls.focus->val; val >= 0;
  632. + val -= DW9719_CTRL_STEPS) {
  633. + ret = dw9719_t_focus_abs(dw9719, val);
  634. + if (ret)
  635. + return ret;
  636. +
  637. + usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10);
  638. + }
  639. +
  640. + return dw9719_power_down(dw9719);
  641. +}
  642. +
  643. +static int __maybe_unused dw9719_resume(struct device *dev)
  644. +{
  645. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  646. + struct dw9719_device *dw9719 = to_dw9719_device(sd);
  647. + int current_focus = dw9719->ctrls.focus->val;
  648. + int ret;
  649. + int val;
  650. +
  651. + ret = dw9719_power_up(dw9719);
  652. + if (ret)
  653. + return ret;
  654. +
  655. + for (val = current_focus % DW9719_CTRL_STEPS; val < current_focus;
  656. + val += DW9719_CTRL_STEPS) {
  657. + ret = dw9719_t_focus_abs(dw9719, val);
  658. + if (ret)
  659. + goto err_power_down;
  660. +
  661. + usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10);
  662. + }
  663. +
  664. + return 0;
  665. +
  666. +err_power_down:
  667. + dw9719_power_down(dw9719);
  668. + return ret;
  669. +}
  670. +
  671. +static int dw9719_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  672. +{
  673. + return pm_runtime_resume_and_get(sd->dev);
  674. +}
  675. +
  676. +static int dw9719_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  677. +{
  678. + pm_runtime_put(sd->dev);
  679. +
  680. + return 0;
  681. +}
  682. +
  683. +static const struct v4l2_subdev_internal_ops dw9719_internal_ops = {
  684. + .open = dw9719_open,
  685. + .close = dw9719_close,
  686. +};
  687. +
  688. +static int dw9719_init_controls(struct dw9719_device *dw9719)
  689. +{
  690. + const struct v4l2_ctrl_ops *ops = &dw9719_ctrl_ops;
  691. + int ret;
  692. +
  693. + ret = v4l2_ctrl_handler_init(&dw9719->ctrls.handler, 1);
  694. + if (ret)
  695. + return ret;
  696. +
  697. + dw9719->ctrls.focus = v4l2_ctrl_new_std(&dw9719->ctrls.handler, ops,
  698. + V4L2_CID_FOCUS_ABSOLUTE, 0,
  699. + DW9719_MAX_FOCUS_POS, 1, 0);
  700. +
  701. + if (dw9719->ctrls.handler.error) {
  702. + dev_err(dw9719->dev, "Error initialising v4l2 ctrls\n");
  703. + ret = dw9719->ctrls.handler.error;
  704. + goto err_free_handler;
  705. + }
  706. +
  707. + dw9719->sd.ctrl_handler = &dw9719->ctrls.handler;
  708. +
  709. + return ret;
  710. +
  711. +err_free_handler:
  712. + v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
  713. + return ret;
  714. +}
  715. +
  716. +static const struct v4l2_subdev_ops dw9719_ops = { };
  717. +
  718. +static int dw9719_probe(struct i2c_client *client)
  719. +{
  720. + struct dw9719_device *dw9719;
  721. + int ret;
  722. +
  723. + dw9719 = devm_kzalloc(&client->dev, sizeof(*dw9719), GFP_KERNEL);
  724. + if (!dw9719)
  725. + return -ENOMEM;
  726. +
  727. + dw9719->client = client;
  728. + dw9719->dev = &client->dev;
  729. +
  730. + dw9719->regulators[0].supply = "vdd";
  731. + /*
  732. + * The DW9719 has only the 1 VDD voltage input, but some PMICs such as
  733. + * the TPS68470 PMIC have I2C passthrough capability, to disconnect the
  734. + * sensor's I2C pins from the I2C bus when the sensors VSIO (Sensor-IO)
  735. + * is off, because some sensors then short these pins to ground;
  736. + * and the DW9719 might sit behind this passthrough, this it needs to
  737. + * enable VSIO as that will also enable the I2C passthrough.
  738. + */
  739. + dw9719->regulators[1].supply = "vsio";
  740. +
  741. + ret = devm_regulator_bulk_get(&client->dev, NUM_REGULATORS,
  742. + dw9719->regulators);
  743. + if (ret)
  744. + return dev_err_probe(&client->dev, ret, "getting regulators\n");
  745. +
  746. + v4l2_i2c_subdev_init(&dw9719->sd, client, &dw9719_ops);
  747. + dw9719->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  748. + dw9719->sd.internal_ops = &dw9719_internal_ops;
  749. +
  750. + ret = dw9719_init_controls(dw9719);
  751. + if (ret)
  752. + return ret;
  753. +
  754. + ret = media_entity_pads_init(&dw9719->sd.entity, 0, NULL);
  755. + if (ret < 0)
  756. + goto err_free_ctrl_handler;
  757. +
  758. + dw9719->sd.entity.function = MEDIA_ENT_F_LENS;
  759. +
  760. + /*
  761. + * We need the driver to work in the event that pm runtime is disable in
  762. + * the kernel, so power up and verify the chip now. In the event that
  763. + * runtime pm is disabled this will leave the chip on, so that the lens
  764. + * will work.
  765. + */
  766. +
  767. + ret = dw9719_power_up(dw9719);
  768. + if (ret)
  769. + goto err_cleanup_media;
  770. +
  771. + ret = dw9719_detect(dw9719);
  772. + if (ret)
  773. + goto err_powerdown;
  774. +
  775. + pm_runtime_set_active(&client->dev);
  776. + pm_runtime_get_noresume(&client->dev);
  777. + pm_runtime_enable(&client->dev);
  778. +
  779. + ret = v4l2_async_register_subdev(&dw9719->sd);
  780. + if (ret < 0)
  781. + goto err_pm_runtime;
  782. +
  783. + pm_runtime_set_autosuspend_delay(&client->dev, 1000);
  784. + pm_runtime_use_autosuspend(&client->dev);
  785. + pm_runtime_put_autosuspend(&client->dev);
  786. +
  787. + return ret;
  788. +
  789. +err_pm_runtime:
  790. + pm_runtime_disable(&client->dev);
  791. + pm_runtime_put_noidle(&client->dev);
  792. +err_powerdown:
  793. + dw9719_power_down(dw9719);
  794. +err_cleanup_media:
  795. + media_entity_cleanup(&dw9719->sd.entity);
  796. +err_free_ctrl_handler:
  797. + v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
  798. +
  799. + return ret;
  800. +}
  801. +
  802. +static void dw9719_remove(struct i2c_client *client)
  803. +{
  804. + struct v4l2_subdev *sd = i2c_get_clientdata(client);
  805. + struct dw9719_device *dw9719 = container_of(sd, struct dw9719_device,
  806. + sd);
  807. +
  808. + pm_runtime_disable(&client->dev);
  809. + v4l2_async_unregister_subdev(sd);
  810. + v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
  811. + media_entity_cleanup(&dw9719->sd.entity);
  812. +}
  813. +
  814. +static const struct i2c_device_id dw9719_id_table[] = {
  815. + { "dw9719" },
  816. + { }
  817. +};
  818. +MODULE_DEVICE_TABLE(i2c, dw9719_id_table);
  819. +
  820. +static const struct dev_pm_ops dw9719_pm_ops = {
  821. + SET_RUNTIME_PM_OPS(dw9719_suspend, dw9719_resume, NULL)
  822. +};
  823. +
  824. +static struct i2c_driver dw9719_i2c_driver = {
  825. + .driver = {
  826. + .name = "dw9719",
  827. + .pm = &dw9719_pm_ops,
  828. + },
  829. + .probe_new = dw9719_probe,
  830. + .remove = dw9719_remove,
  831. + .id_table = dw9719_id_table,
  832. +};
  833. +module_i2c_driver(dw9719_i2c_driver);
  834. +
  835. +MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
  836. +MODULE_DESCRIPTION("DW9719 VCM Driver");
  837. +MODULE_LICENSE("GPL");
  838. --
  839. 2.41.0
  840. From a303fe2af8bff9c4877ad2e7da1b6e3b6d0eb8a0 Mon Sep 17 00:00:00 2001
  841. From: Maximilian Luz <luzmaximilian@gmail.com>
  842. Date: Fri, 15 Jul 2022 23:48:00 +0200
  843. Subject: [PATCH] drivers/media/i2c: Fix DW9719 dependencies
  844. It should depend on VIDEO_DEV instead of VIDEO_V4L2.
  845. Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
  846. Patchset: cameras
  847. ---
  848. drivers/media/i2c/Kconfig | 2 +-
  849. 1 file changed, 1 insertion(+), 1 deletion(-)
  850. diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
  851. index e759470a0b6b..dbc6d20efbe5 100644
  852. --- a/drivers/media/i2c/Kconfig
  853. +++ b/drivers/media/i2c/Kconfig
  854. @@ -889,7 +889,7 @@ config VIDEO_DW9714
  855. config VIDEO_DW9719
  856. tristate "DW9719 lens voice coil support"
  857. - depends on I2C && VIDEO_V4L2
  858. + depends on I2C && VIDEO_DEV
  859. select MEDIA_CONTROLLER
  860. select VIDEO_V4L2_SUBDEV_API
  861. select V4L2_ASYNC
  862. --
  863. 2.41.0
  864. From 9b44fcd2c435a990e10c3294cfa6332cb5cf3330 Mon Sep 17 00:00:00 2001
  865. From: Daniel Scally <dan.scally@ideasonboard.com>
  866. Date: Thu, 2 Mar 2023 12:59:39 +0000
  867. Subject: [PATCH] platform/x86: int3472: Remap reset GPIO for INT347E
  868. ACPI _HID INT347E represents the OmniVision 7251 camera sensor. The
  869. driver for this sensor expects a single pin named "enable", but on
  870. some Microsoft Surface platforms the sensor is assigned a single
  871. GPIO who's type flag is INT3472_GPIO_TYPE_RESET.
  872. Remap the GPIO pin's function from "reset" to "enable". This is done
  873. outside of the existing remap table since it is a more widespread
  874. discrepancy than that method is designed for. Additionally swap the
  875. polarity of the pin to match the driver's expectation.
  876. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
  877. Patchset: cameras
  878. ---
  879. drivers/platform/x86/intel/int3472/discrete.c | 14 ++++++++++++++
  880. 1 file changed, 14 insertions(+)
  881. diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
  882. index f064da74f50a..2064b3bbe530 100644
  883. --- a/drivers/platform/x86/intel/int3472/discrete.c
  884. +++ b/drivers/platform/x86/intel/int3472/discrete.c
  885. @@ -98,6 +98,9 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
  886. {
  887. const struct int3472_sensor_config *sensor_config;
  888. char *path = agpio->resource_source.string_ptr;
  889. + const struct acpi_device_id ov7251_ids[] = {
  890. + { "INT347E" },
  891. + };
  892. struct gpiod_lookup *table_entry;
  893. struct acpi_device *adev;
  894. acpi_handle handle;
  895. @@ -120,6 +123,17 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
  896. }
  897. }
  898. + /*
  899. + * In addition to the function remap table we need to bulk remap the
  900. + * "reset" GPIO for the OmniVision 7251 sensor, as the driver for that
  901. + * expects its only GPIO pin to be called "enable" (and to have the
  902. + * opposite polarity).
  903. + */
  904. + if (!strcmp(func, "reset") && !acpi_match_device_ids(int3472->sensor, ov7251_ids)) {
  905. + func = "enable";
  906. + polarity = GPIO_ACTIVE_HIGH;
  907. + }
  908. +
  909. /* Functions mapped to NULL should not be mapped to the sensor */
  910. if (!func)
  911. return 0;
  912. --
  913. 2.41.0
  914. From 69e4eebad974fac3781ac118ad3d38471c09786f Mon Sep 17 00:00:00 2001
  915. From: Daniel Scally <dan.scally@ideasonboard.com>
  916. Date: Tue, 21 Mar 2023 13:45:26 +0000
  917. Subject: [PATCH] media: i2c: Clarify that gain is Analogue gain in OV7251
  918. Update the control ID for the gain control in the ov7251 driver to
  919. V4L2_CID_ANALOGUE_GAIN.
  920. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
  921. Patchset: cameras
  922. ---
  923. drivers/media/i2c/ov7251.c | 4 ++--
  924. 1 file changed, 2 insertions(+), 2 deletions(-)
  925. diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c
  926. index 88e987435285..ff7b2c26da83 100644
  927. --- a/drivers/media/i2c/ov7251.c
  928. +++ b/drivers/media/i2c/ov7251.c
  929. @@ -1051,7 +1051,7 @@ static int ov7251_s_ctrl(struct v4l2_ctrl *ctrl)
  930. case V4L2_CID_EXPOSURE:
  931. ret = ov7251_set_exposure(ov7251, ctrl->val);
  932. break;
  933. - case V4L2_CID_GAIN:
  934. + case V4L2_CID_ANALOGUE_GAIN:
  935. ret = ov7251_set_gain(ov7251, ctrl->val);
  936. break;
  937. case V4L2_CID_TEST_PATTERN:
  938. @@ -1551,7 +1551,7 @@ static int ov7251_init_ctrls(struct ov7251 *ov7251)
  939. ov7251->exposure = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops,
  940. V4L2_CID_EXPOSURE, 1, 32, 1, 32);
  941. ov7251->gain = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops,
  942. - V4L2_CID_GAIN, 16, 1023, 1, 16);
  943. + V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 16);
  944. v4l2_ctrl_new_std_menu_items(&ov7251->ctrls, &ov7251_ctrl_ops,
  945. V4L2_CID_TEST_PATTERN,
  946. ARRAY_SIZE(ov7251_test_pattern_menu) - 1,
  947. --
  948. 2.41.0
  949. From f8930375ce32eacf48740e052aef49926d9dcf23 Mon Sep 17 00:00:00 2001
  950. From: Daniel Scally <dan.scally@ideasonboard.com>
  951. Date: Wed, 22 Mar 2023 11:01:42 +0000
  952. Subject: [PATCH] media: v4l2-core: Acquire privacy led in
  953. v4l2_async_register_subdev()
  954. The current call to v4l2_subdev_get_privacy_led() is contained in
  955. v4l2_async_register_subdev_sensor(), but that function isn't used by
  956. all the sensor drivers. Move the acquisition of the privacy led to
  957. v4l2_async_register_subdev() instead.
  958. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
  959. Patchset: cameras
  960. ---
  961. drivers/media/v4l2-core/v4l2-async.c | 4 ++++
  962. drivers/media/v4l2-core/v4l2-fwnode.c | 4 ----
  963. 2 files changed, 4 insertions(+), 4 deletions(-)
  964. diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
  965. index b16b5f4cb91e..33739a979cbc 100644
  966. --- a/drivers/media/v4l2-core/v4l2-async.c
  967. +++ b/drivers/media/v4l2-core/v4l2-async.c
  968. @@ -760,6 +760,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
  969. struct v4l2_async_notifier *notifier;
  970. int ret;
  971. + ret = v4l2_subdev_get_privacy_led(sd);
  972. + if (ret < 0)
  973. + return ret;
  974. +
  975. /*
  976. * No reference taken. The reference is held by the device
  977. * (struct v4l2_subdev.dev), and async sub-device does not
  978. diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
  979. index 049c2f2001ea..f8c3e40b2b71 100644
  980. --- a/drivers/media/v4l2-core/v4l2-fwnode.c
  981. +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
  982. @@ -1304,10 +1304,6 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd)
  983. v4l2_async_nf_init(notifier);
  984. - ret = v4l2_subdev_get_privacy_led(sd);
  985. - if (ret < 0)
  986. - goto out_cleanup;
  987. -
  988. ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier);
  989. if (ret < 0)
  990. goto out_cleanup;
  991. --
  992. 2.41.0
  993. From 65dbdc33eef95685b923b632429a1098eeab54cc Mon Sep 17 00:00:00 2001
  994. From: Kate Hsuan <hpa@redhat.com>
  995. Date: Tue, 21 Mar 2023 23:37:16 +0800
  996. Subject: [PATCH] platform: x86: int3472: Add MFD cell for tps68470 LED
  997. Add MFD cell for tps68470-led.
  998. Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
  999. Signed-off-by: Kate Hsuan <hpa@redhat.com>
  1000. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  1001. Patchset: cameras
  1002. ---
  1003. drivers/platform/x86/intel/int3472/tps68470.c | 5 +++--
  1004. 1 file changed, 3 insertions(+), 2 deletions(-)
  1005. diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
  1006. index 6a0ff035cf20..2a7d01d3abc8 100644
  1007. --- a/drivers/platform/x86/intel/int3472/tps68470.c
  1008. +++ b/drivers/platform/x86/intel/int3472/tps68470.c
  1009. @@ -17,7 +17,7 @@
  1010. #define DESIGNED_FOR_CHROMEOS 1
  1011. #define DESIGNED_FOR_WINDOWS 2
  1012. -#define TPS68470_WIN_MFD_CELL_COUNT 3
  1013. +#define TPS68470_WIN_MFD_CELL_COUNT 4
  1014. static const struct mfd_cell tps68470_cros[] = {
  1015. { .name = "tps68470-gpio" },
  1016. @@ -200,7 +200,8 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
  1017. cells[1].name = "tps68470-regulator";
  1018. cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
  1019. cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
  1020. - cells[2].name = "tps68470-gpio";
  1021. + cells[2].name = "tps68470-led";
  1022. + cells[3].name = "tps68470-gpio";
  1023. for (i = 0; i < board_data->n_gpiod_lookups; i++)
  1024. gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
  1025. --
  1026. 2.41.0
  1027. From dada2a23cf8f8634589b31b65baebd27eb3b8053 Mon Sep 17 00:00:00 2001
  1028. From: Kate Hsuan <hpa@redhat.com>
  1029. Date: Tue, 21 Mar 2023 23:37:17 +0800
  1030. Subject: [PATCH] include: mfd: tps68470: Add masks for LEDA and LEDB
  1031. Add flags for both LEDA(TPS68470_ILEDCTL_ENA), LEDB
  1032. (TPS68470_ILEDCTL_ENB), and current control mask for LEDB
  1033. (TPS68470_ILEDCTL_CTRLB)
  1034. Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
  1035. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  1036. Signed-off-by: Kate Hsuan <hpa@redhat.com>
  1037. Patchset: cameras
  1038. ---
  1039. include/linux/mfd/tps68470.h | 5 +++++
  1040. 1 file changed, 5 insertions(+)
  1041. diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h
  1042. index 7807fa329db0..2d2abb25b944 100644
  1043. --- a/include/linux/mfd/tps68470.h
  1044. +++ b/include/linux/mfd/tps68470.h
  1045. @@ -34,6 +34,7 @@
  1046. #define TPS68470_REG_SGPO 0x22
  1047. #define TPS68470_REG_GPDI 0x26
  1048. #define TPS68470_REG_GPDO 0x27
  1049. +#define TPS68470_REG_ILEDCTL 0x28
  1050. #define TPS68470_REG_VCMVAL 0x3C
  1051. #define TPS68470_REG_VAUX1VAL 0x3D
  1052. #define TPS68470_REG_VAUX2VAL 0x3E
  1053. @@ -94,4 +95,8 @@
  1054. #define TPS68470_GPIO_MODE_OUT_CMOS 2
  1055. #define TPS68470_GPIO_MODE_OUT_ODRAIN 3
  1056. +#define TPS68470_ILEDCTL_ENA BIT(2)
  1057. +#define TPS68470_ILEDCTL_ENB BIT(6)
  1058. +#define TPS68470_ILEDCTL_CTRLB GENMASK(5, 4)
  1059. +
  1060. #endif /* __LINUX_MFD_TPS68470_H */
  1061. --
  1062. 2.41.0
  1063. From a59248a30515abd97ce0eb04573fcfbae53d487c Mon Sep 17 00:00:00 2001
  1064. From: Kate Hsuan <hpa@redhat.com>
  1065. Date: Tue, 21 Mar 2023 23:37:18 +0800
  1066. Subject: [PATCH] leds: tps68470: Add LED control for tps68470
  1067. There are two LED controllers, LEDA indicator LED and LEDB flash LED for
  1068. tps68470. LEDA can be enabled by setting TPS68470_ILEDCTL_ENA. Moreover,
  1069. tps68470 provides four levels of power status for LEDB. If the
  1070. properties called "ti,ledb-current" can be found, the current will be
  1071. set according to the property values. These two LEDs can be controlled
  1072. through the LED class of sysfs (tps68470-leda and tps68470-ledb).
  1073. Signed-off-by: Kate Hsuan <hpa@redhat.com>
  1074. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  1075. Patchset: cameras
  1076. ---
  1077. drivers/leds/Kconfig | 12 +++
  1078. drivers/leds/Makefile | 1 +
  1079. drivers/leds/leds-tps68470.c | 185 +++++++++++++++++++++++++++++++++++
  1080. 3 files changed, 198 insertions(+)
  1081. create mode 100644 drivers/leds/leds-tps68470.c
  1082. diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
  1083. index aaa9140bc351..1fb892c9acf1 100644
  1084. --- a/drivers/leds/Kconfig
  1085. +++ b/drivers/leds/Kconfig
  1086. @@ -827,6 +827,18 @@ config LEDS_TPS6105X
  1087. It is a single boost converter primarily for white LEDs and
  1088. audio amplifiers.
  1089. +config LEDS_TPS68470
  1090. + tristate "LED support for TI TPS68470"
  1091. + depends on LEDS_CLASS
  1092. + depends on INTEL_SKL_INT3472
  1093. + help
  1094. + This driver supports TPS68470 PMIC with LED chip.
  1095. + It provides two LED controllers, with the ability to drive 2
  1096. + indicator LEDs and 2 flash LEDs.
  1097. +
  1098. + To compile this driver as a module, choose M and it will be
  1099. + called leds-tps68470
  1100. +
  1101. config LEDS_IP30
  1102. tristate "LED support for SGI Octane machines"
  1103. depends on LEDS_CLASS
  1104. diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
  1105. index d30395d11fd8..515a69953e73 100644
  1106. --- a/drivers/leds/Makefile
  1107. +++ b/drivers/leds/Makefile
  1108. @@ -80,6 +80,7 @@ obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
  1109. obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
  1110. obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o
  1111. obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o
  1112. +obj-$(CONFIG_LEDS_TPS68470) += leds-tps68470.o
  1113. obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o
  1114. obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
  1115. obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
  1116. diff --git a/drivers/leds/leds-tps68470.c b/drivers/leds/leds-tps68470.c
  1117. new file mode 100644
  1118. index 000000000000..35aeb5db89c8
  1119. --- /dev/null
  1120. +++ b/drivers/leds/leds-tps68470.c
  1121. @@ -0,0 +1,185 @@
  1122. +// SPDX-License-Identifier: GPL-2.0
  1123. +/*
  1124. + * LED driver for TPS68470 PMIC
  1125. + *
  1126. + * Copyright (C) 2023 Red Hat
  1127. + *
  1128. + * Authors:
  1129. + * Kate Hsuan <hpa@redhat.com>
  1130. + */
  1131. +
  1132. +#include <linux/leds.h>
  1133. +#include <linux/mfd/tps68470.h>
  1134. +#include <linux/module.h>
  1135. +#include <linux/platform_device.h>
  1136. +#include <linux/property.h>
  1137. +#include <linux/regmap.h>
  1138. +
  1139. +
  1140. +#define lcdev_to_led(led_cdev) \
  1141. + container_of(led_cdev, struct tps68470_led, lcdev)
  1142. +
  1143. +#define led_to_tps68470(led, index) \
  1144. + container_of(led, struct tps68470_device, leds[index])
  1145. +
  1146. +enum tps68470_led_ids {
  1147. + TPS68470_ILED_A,
  1148. + TPS68470_ILED_B,
  1149. + TPS68470_NUM_LEDS
  1150. +};
  1151. +
  1152. +static const char *tps68470_led_names[] = {
  1153. + [TPS68470_ILED_A] = "tps68470-iled_a",
  1154. + [TPS68470_ILED_B] = "tps68470-iled_b",
  1155. +};
  1156. +
  1157. +struct tps68470_led {
  1158. + unsigned int led_id;
  1159. + struct led_classdev lcdev;
  1160. +};
  1161. +
  1162. +struct tps68470_device {
  1163. + struct device *dev;
  1164. + struct regmap *regmap;
  1165. + struct tps68470_led leds[TPS68470_NUM_LEDS];
  1166. +};
  1167. +
  1168. +enum ctrlb_current {
  1169. + CTRLB_2MA = 0,
  1170. + CTRLB_4MA = 1,
  1171. + CTRLB_8MA = 2,
  1172. + CTRLB_16MA = 3,
  1173. +};
  1174. +
  1175. +static int tps68470_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness)
  1176. +{
  1177. + struct tps68470_led *led = lcdev_to_led(led_cdev);
  1178. + struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id);
  1179. + struct regmap *regmap = tps68470->regmap;
  1180. +
  1181. + switch (led->led_id) {
  1182. + case TPS68470_ILED_A:
  1183. + return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENA,
  1184. + brightness ? TPS68470_ILEDCTL_ENA : 0);
  1185. + case TPS68470_ILED_B:
  1186. + return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENB,
  1187. + brightness ? TPS68470_ILEDCTL_ENB : 0);
  1188. + }
  1189. + return -EINVAL;
  1190. +}
  1191. +
  1192. +static enum led_brightness tps68470_brightness_get(struct led_classdev *led_cdev)
  1193. +{
  1194. + struct tps68470_led *led = lcdev_to_led(led_cdev);
  1195. + struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id);
  1196. + struct regmap *regmap = tps68470->regmap;
  1197. + int ret = 0;
  1198. + int value = 0;
  1199. +
  1200. + ret = regmap_read(regmap, TPS68470_REG_ILEDCTL, &value);
  1201. + if (ret)
  1202. + return dev_err_probe(led_cdev->dev, -EINVAL, "failed on reading register\n");
  1203. +
  1204. + switch (led->led_id) {
  1205. + case TPS68470_ILED_A:
  1206. + value = value & TPS68470_ILEDCTL_ENA;
  1207. + break;
  1208. + case TPS68470_ILED_B:
  1209. + value = value & TPS68470_ILEDCTL_ENB;
  1210. + break;
  1211. + }
  1212. +
  1213. + return value ? LED_ON : LED_OFF;
  1214. +}
  1215. +
  1216. +
  1217. +static int tps68470_ledb_current_init(struct platform_device *pdev,
  1218. + struct tps68470_device *tps68470)
  1219. +{
  1220. + int ret = 0;
  1221. + unsigned int curr;
  1222. +
  1223. + /* configure LEDB current if the properties can be got */
  1224. + if (!device_property_read_u32(&pdev->dev, "ti,ledb-current", &curr)) {
  1225. + if (curr > CTRLB_16MA) {
  1226. + dev_err(&pdev->dev,
  1227. + "Invalid LEDB current value: %d\n",
  1228. + curr);
  1229. + return -EINVAL;
  1230. + }
  1231. + ret = regmap_update_bits(tps68470->regmap, TPS68470_REG_ILEDCTL,
  1232. + TPS68470_ILEDCTL_CTRLB, curr);
  1233. + }
  1234. + return ret;
  1235. +}
  1236. +
  1237. +static int tps68470_leds_probe(struct platform_device *pdev)
  1238. +{
  1239. + int i = 0;
  1240. + int ret = 0;
  1241. + struct tps68470_device *tps68470;
  1242. + struct tps68470_led *led;
  1243. + struct led_classdev *lcdev;
  1244. +
  1245. + tps68470 = devm_kzalloc(&pdev->dev, sizeof(struct tps68470_device),
  1246. + GFP_KERNEL);
  1247. + if (!tps68470)
  1248. + return -ENOMEM;
  1249. +
  1250. + tps68470->dev = &pdev->dev;
  1251. + tps68470->regmap = dev_get_drvdata(pdev->dev.parent);
  1252. +
  1253. + for (i = 0; i < TPS68470_NUM_LEDS; i++) {
  1254. + led = &tps68470->leds[i];
  1255. + lcdev = &led->lcdev;
  1256. +
  1257. + led->led_id = i;
  1258. +
  1259. + lcdev->name = devm_kasprintf(tps68470->dev, GFP_KERNEL, "%s::%s",
  1260. + tps68470_led_names[i], LED_FUNCTION_INDICATOR);
  1261. + if (!lcdev->name)
  1262. + return -ENOMEM;
  1263. +
  1264. + lcdev->max_brightness = 1;
  1265. + lcdev->brightness = 0;
  1266. + lcdev->brightness_set_blocking = tps68470_brightness_set;
  1267. + lcdev->brightness_get = tps68470_brightness_get;
  1268. + lcdev->dev = &pdev->dev;
  1269. +
  1270. + ret = devm_led_classdev_register(tps68470->dev, lcdev);
  1271. + if (ret) {
  1272. + dev_err_probe(tps68470->dev, ret,
  1273. + "error registering led\n");
  1274. + goto err_exit;
  1275. + }
  1276. +
  1277. + if (i == TPS68470_ILED_B) {
  1278. + ret = tps68470_ledb_current_init(pdev, tps68470);
  1279. + if (ret)
  1280. + goto err_exit;
  1281. + }
  1282. + }
  1283. +
  1284. +err_exit:
  1285. + if (ret) {
  1286. + for (i = 0; i < TPS68470_NUM_LEDS; i++) {
  1287. + if (tps68470->leds[i].lcdev.name)
  1288. + devm_led_classdev_unregister(&pdev->dev,
  1289. + &tps68470->leds[i].lcdev);
  1290. + }
  1291. + }
  1292. +
  1293. + return ret;
  1294. +}
  1295. +static struct platform_driver tps68470_led_driver = {
  1296. + .driver = {
  1297. + .name = "tps68470-led",
  1298. + },
  1299. + .probe = tps68470_leds_probe,
  1300. +};
  1301. +
  1302. +module_platform_driver(tps68470_led_driver);
  1303. +
  1304. +MODULE_ALIAS("platform:tps68470-led");
  1305. +MODULE_DESCRIPTION("LED driver for TPS68470 PMIC");
  1306. +MODULE_LICENSE("GPL v2");
  1307. --
  1308. 2.41.0