Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp7721239ioo; Fri, 3 Jun 2022 12:02:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxA2Mlr/azjcjseYOZ6VwwGEAetHqiPVSOUo4U+04MAghPnA1rlBbu+FNfSusNTe+aG1uq/ X-Received: by 2002:a63:2a0d:0:b0:3ab:392c:f45c with SMTP id q13-20020a632a0d000000b003ab392cf45cmr10216237pgq.575.1654282944055; Fri, 03 Jun 2022 12:02:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654282944; cv=none; d=google.com; s=arc-20160816; b=oXjQJ5DjPjBwXFsRa1O5GZpV1E5oNFPVfzPIxe8Dm5BlhGf9F7jkpBJkl6GPLHDK6d q0ZeYm38CXi53W4Ux502bDx3jqQ9FaRgQTuM92/jfoELe+7CiVM7PVkenGCgXrKs4asJ EbQzBztOBPKjmLcaqdiqnjlka98y9GJRjdvM7otMloRXS/D3DwbNV4QdXafvTla8j14G QmxFmBabWhBwj8D5abhC8aiNnB0DlDZxpm0kvfG8JqQu02GAL+ydOqUqolcq2gtlOjvE 1lSWemKs4uvRcMcPZ09x0YBGOeTv9R+NhnT69ooKQYcPiMmPOcTiOrNGRM6Q81NxZGVY VcEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=rb78/Si50YHRG3/zeIdBErQ6GzrBGzyMy6c/2Qru9iA=; b=sjrJwWcB2EXdXCSMfUoDcnI8dNuG8OyoavHaGK/eYIgqcxGWzZF1c6PbX9lircJYC3 a5Le3QYS/DkG/Yr/MY0wXnv+fbeYYFZOa7EbNY5ItMxoHLeuj+4BpywiWlAm/V3v2/wt I/NYfYNjL+MCm9P6yA8Ha0QHp31LVKLMzBPz7sbNUJ2jY4IXyH+DM/PE/TVF+07jf4Mx LAIV8Dme7th+KlfvKN9wFwTmjbhhSQmxCwMfn0woBMtmHz9BPchE6HVHTy4CkcvxhJjo szPXwEnt5DUtJ93trZA90EE9PPMXDxjtv0uHdrpY1sMLG7Q+NUywhX/9QrQSxxKVsZOg kXng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=TIwX3QBF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k9-20020a170902ce0900b0015873958cc9si11757237plg.515.2022.06.03.12.02.09; Fri, 03 Jun 2022 12:02:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=TIwX3QBF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238260AbiFBSWu (ORCPT + 99 others); Thu, 2 Jun 2022 14:22:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57026 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238173AbiFBSWf (ORCPT ); Thu, 2 Jun 2022 14:22:35 -0400 Received: from mail-io1-xd36.google.com (mail-io1-xd36.google.com [IPv6:2607:f8b0:4864:20::d36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9DDB17E19; Thu, 2 Jun 2022 11:22:27 -0700 (PDT) Received: by mail-io1-xd36.google.com with SMTP id 2so5590431iou.5; Thu, 02 Jun 2022 11:22:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=rb78/Si50YHRG3/zeIdBErQ6GzrBGzyMy6c/2Qru9iA=; b=TIwX3QBFC7A8jcA1/ieNV9CVbcphYpQaITGJkvXqeR9RjVRF0E0XsBODPKVouqudI1 yot70cL06RMduvm13bd1wse+JGt21OYGX1ZwbrLxqEZQh0mu6KVD3iaqZ8qv9a2YBkco ItLjawD46ESPW3i7QNZXxgrDi3eE85JW400V1a+iwg9wSk7C6O3JggKToM89pIsyQ039 ng72vAyGicyCDZuW8AvVBYDp2NdNzOWTvKH7N0iRR2rniHvsAWP8MXOjKVDsd98puJ55 KhfXup5QcNrvuCl717Jj+2EHY1H3vtZvLvcXCBS9WbFnt1sT1zQgQPo0O03yN/wLzoh1 n/Fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=rb78/Si50YHRG3/zeIdBErQ6GzrBGzyMy6c/2Qru9iA=; b=jpj68MMw11xFHEEOnCC1shex+6JA/jHL+v6uMqsZBpYq+jIP1mnvu+YGuVV9TGoKDf rdfIYQgi5rToIgmzR0roJ9mVSiE8deV67oopHbzJbagcaCgZSsr095vbBecyWm2BK32M pQLou05yiavaByQp/ipA589etcFt4R6YhsxVuBME9ZCs3KVEjOz/zrvOcoT31GT9tTXV B+sEhtkGpq0h6Q4D9/IXSEGVY6f2BGQVzY8ihrkJGJeE/lnyeYE/tLlPrl1KAFhQebK+ qmj6mLlg0tSgcd7zmsp38IFW3JHxIEzprprgyDbNDiKJ3iBjWEuRzOEu9kGNdaZ+l/e5 6Jzw== X-Gm-Message-State: AOAM532sDwgzlKtfbYuvgrPTNIkxmj7uXmS+wltgeFSFKnLKIbLRTpUt mpyauU1+6nJpGXioy5ci1mGrFJieb1KZOZ/1PhY= X-Received: by 2002:a02:9f8b:0:b0:32e:7bf1:bd with SMTP id a11-20020a029f8b000000b0032e7bf100bdmr3866136jam.2.1654194147191; Thu, 02 Jun 2022 11:22:27 -0700 (PDT) MIME-Version: 1.0 References: <20220531111900.19422-1-peterwu.pub@gmail.com> <20220531111900.19422-11-peterwu.pub@gmail.com> <20220531142102.00007df0@Huawei.com> In-Reply-To: <20220531142102.00007df0@Huawei.com> From: ChiaEn Wu Date: Fri, 3 Jun 2022 02:22:16 +0800 Message-ID: Subject: Re: [RESEND 10/14] iio: adc: mt6370: Add Mediatek MT6370 support To: Jonathan Cameron Cc: lee.jones@linaro.org, daniel.thompson@linaro.org, jingoohan1@gmail.com, pavel@ucw.cz, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, matthias.bgg@gmail.com, sre@kernel.org, chunfeng.yun@mediatek.com, gregkh@linuxfoundation.org, jic23@kernel.org, lars@metafoo.de, lgirdwood@gmail.com, broonie@kernel.org, linux@roeck-us.net, heikki.krogerus@linux.intel.com, deller@gmx.de, ChiYuan Huang , alice_chen@richtek.com, chiaen_wu@richtek.com, dri-devel@lists.freedesktop.org, linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, linux-iio@vger.kernel.org, linux-fbdev@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Jonathan, Sorry for sending the same email again. I miss to reply all in the last ema= il.. Thanks for your valuable suggestions! Jonathan Cameron =E6=96=BC 2022=E5=B9=B45=E6= =9C=8831=E6=97=A5 =E9=80=B1=E4=BA=8C =E4=B8=8B=E5=8D=889:21=E5=AF=AB=E9=81= =93=EF=BC=9A > > On Tue, 31 May 2022 19:18:56 +0800 > ChiaEn Wu wrote: > > > From: ChiaEn Wu > > > > Add Mediatek MT6370 ADC support. > > > > Signed-off-by: ChiaEn Wu > > Hi ChiaEn, > > A few comments inline. > > Thanks, > > Jonathan > > > --- > > drivers/iio/adc/Kconfig | 9 ++ > > drivers/iio/adc/Makefile | 1 + > > drivers/iio/adc/mt6370-adc.c | 257 +++++++++++++++++++++++++++++++++++ > > 3 files changed, 267 insertions(+) > > create mode 100644 drivers/iio/adc/mt6370-adc.c > > > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > > index 71ab0a06aa82..d7932dd9b773 100644 > > --- a/drivers/iio/adc/Kconfig > > +++ b/drivers/iio/adc/Kconfig > > @@ -737,6 +737,15 @@ config MEDIATEK_MT6360_ADC > > is used in smartphones and tablets and supports a 11 channel > > general purpose ADC. > > > > +config MEDIATEK_MT6370_ADC > > + tristate "Mediatek MT6370 ADC driver" > > + depends on MFD_MT6370 > > + help > > + Say Y here to enable MT6370 ADC support. > > + Integrated for System Monitoring includes > > The wrapping of this text needs cleaning up. > > > + is used in smartphones and tablets and supports a 9 channel > > + general purpose ADC. > > + > > config MEDIATEK_MT6577_AUXADC > > tristate "MediaTek AUXADC driver" > > depends on ARCH_MEDIATEK || COMPILE_TEST > > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > > index 39d806f6d457..0ce285c7e2d0 100644 > > --- a/drivers/iio/adc/Makefile > > +++ b/drivers/iio/adc/Makefile > > @@ -68,6 +68,7 @@ obj-$(CONFIG_MCP320X) +=3D mcp320x.o > > obj-$(CONFIG_MCP3422) +=3D mcp3422.o > > obj-$(CONFIG_MCP3911) +=3D mcp3911.o > > obj-$(CONFIG_MEDIATEK_MT6360_ADC) +=3D mt6360-adc.o > > +obj-$(CONFIG_MEDIATEK_MT6370_ADC) +=3D mt6370-adc.o > > obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) +=3D mt6577_auxadc.o > > obj-$(CONFIG_MEN_Z188_ADC) +=3D men_z188_adc.o > > obj-$(CONFIG_MESON_SARADC) +=3D meson_saradc.o > > diff --git a/drivers/iio/adc/mt6370-adc.c b/drivers/iio/adc/mt6370-adc.= c > > new file mode 100644 > > index 000000000000..3320ebca17ad > > --- /dev/null > > +++ b/drivers/iio/adc/mt6370-adc.c > > @@ -0,0 +1,257 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > Not seeing any interrupt support in here. Sorry for that I forgot remove this line, I'll refine it in the next patch. > > > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define MT6370_REG_CHG_CTRL3 0x113 /* AICR */ > > +#define MT6370_REG_CHG_CTRL7 0x117 /* ICHG */ > > +#define MT6370_REG_CHG_ADC 0x121 > > +#define MT6370_REG_ADC_DATA_H 0x14C > > + > > +#define MT6370_ADC_START_MASK BIT(0) > > +#define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4) > > +#define MT6370_AICR_ICHG_MASK GENMASK(7, 2) > > + > > +#define MT6370_ADC_CHAN_SHIFT 4 > > Prefer using a mask and then FIELD_PREP OK, I got it! > > > + > > +#define MT6370_AICR_400MA 0x6 > > +#define MT6370_ICHG_500MA 0x4 > > +#define MT6370_ICHG_900MA 0x8 > > + > > +#define ADC_CONV_TIME_US 35000 > > +#define ADC_CONV_POLLING_TIME 1000 > > + > > +struct mt6370_adc_data { > > + struct device *dev; > > + struct regmap *regmap; > > + struct mutex lock; > > All locks need documentation. What is the scope of the lock? > Looks like it protects device state when doing setup, wait for read, read > cycles. This mutex lock is for preventing the different adc channel from being read at the same time. So, if I just change its name to adc_chan_lock or adc_lock and add the comment for this mutex lock, does this change meet your requirement? > > > +}; > > + > > +static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int c= han, > > + unsigned long addr, int *val) > > +{ > > + __be16 be_val; > > + unsigned int reg_val; > > + int ret; > > + > > + mutex_lock(&priv->lock); > > + > > + reg_val =3D MT6370_ADC_START_MASK | (addr << MT6370_ADC_CHAN_SHIF= T); > > FIELD_PREP for that shift? I got it! I'll refine it in the next patch. > > > + ret =3D regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val); > > + if (ret) > > + goto adc_unlock; > > + > > + msleep(ADC_CONV_TIME_US / 1000); > > + > > + ret =3D regmap_read_poll_timeout(priv->regmap, > > + MT6370_REG_CHG_ADC, reg_val, > > + !(reg_val & MT6370_ADC_START_MASK)= , > > + ADC_CONV_POLLING_TIME, > > + ADC_CONV_TIME_US * 3); > > + if (ret) { > > + if (ret =3D=3D -ETIMEDOUT) > > + dev_err(priv->dev, "Failed to wait adc conversion= \n"); > > + goto adc_unlock; > > + } > > + > > + ret =3D regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H, > > + &be_val, sizeof(be_val)); > > + if (ret) > > + goto adc_unlock; > > + > > + *val =3D be16_to_cpu(be_val); > > + ret =3D IIO_VAL_INT; > > + > > +adc_unlock: > > + mutex_unlock(&priv->lock); > > + > > + return ret; > > +} > > + > > +static int mt6370_adc_read_scale(struct mt6370_adc_data *priv, > > + int chan, int *val1, int *val2) > > +{ > > + unsigned int reg_val; > > + int ret; > > + > > + switch (chan) { > > + case MT6370_CHAN_VBAT: > > + case MT6370_CHAN_VSYS: > > + case MT6370_CHAN_CHG_VDDP: > > + *val1 =3D 5000; > > This seems very large. Voltages are in millivolts > as per Documentation/ABI/testing/sysfs-bus-iio > and this means each step is 5 volts. > > So value in mv is currently 5 * _raw > OK, I got it. Also, I will add the ABI file in the next version. Thanks! > > > > + return IIO_VAL_INT; > > + case MT6370_CHAN_IBUS: > > + ret =3D regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, &= reg_val); > > + if (ret) > > + return ret; > > + > > + reg_val =3D FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); > > + if (reg_val < MT6370_AICR_400MA) > > + *val1 =3D 33500; > > + else > > + *val1 =3D 50000; > > + > > + return IIO_VAL_INT; > > + case MT6370_CHAN_IBAT: > > + ret =3D regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, &= reg_val); > > + if (ret) > > + return ret; > > + > > + reg_val =3D FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); > > + if (reg_val < MT6370_ICHG_500MA) > > + *val1 =3D 23750; > > + else if (reg_val >=3D MT6370_ICHG_500MA && > > + reg_val < MT6370_ICHG_900MA) > > + *val1 =3D 26800; > > + else > > + *val1 =3D 50000; > > + > > + return IIO_VAL_INT; > > + case MT6370_CHAN_VBUSDIV5: > > + *val1 =3D 25000; > > + return IIO_VAL_INT; > > + case MT6370_CHAN_VBUSDIV2: > > + *val1 =3D 50000; > > + return IIO_VAL_INT; > > + case MT6370_CHAN_TS_BAT: > > + *val1 =3D 25; > > + *val2 =3D 10000; > > + return IIO_VAL_FRACTIONAL; > > + case MT6370_CHAN_TEMP_JC: > > + *val1 =3D 2; > > + return IIO_VAL_INT; > > + } > > + > > + return -EINVAL; > > +} > > + > > +static int mt6370_adc_read_offset(struct mt6370_adc_data *priv, > > + int chan, int *val) > > +{ > > + *val =3D (chan =3D=3D MT6370_CHAN_TEMP_JC) ? -20 : 0; > > Offset default is 0, so for channels where it doesn't apply don't > provide the offset attribute at all. > OK! > > + return IIO_VAL_INT; > > +} > > + > > +static int mt6370_adc_read_raw(struct iio_dev *iio_dev, > > + const struct iio_chan_spec *chan, > > + int *val, int *val2, long mask) > > +{ > > + struct mt6370_adc_data *priv =3D iio_priv(iio_dev); > > + > > + switch (mask) { > > + case IIO_CHAN_INFO_RAW: > > + return mt6370_adc_read_channel(priv, chan->channel, > > + chan->address, val); > > + case IIO_CHAN_INFO_SCALE: > > + return mt6370_adc_read_scale(priv, chan->channel, val, va= l2); > > + case IIO_CHAN_INFO_OFFSET: > > + return mt6370_adc_read_offset(priv, chan->channel, val); > > + } > > + > > + return -EINVAL; > > +} > > + > > +static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] =3D { > > Perhaps define an enum with which to index this and the chan spec > and hence ensure they end up matching. > [vbusdiv5] =3D "vbusdiv5", etc > Do you mean that I can refine this const char array to the following array?= ? static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] =3D { [MT6370_CHAN_VBUSDIV5] =3D "vbusdiv5", [MT6370_CHAN_VBUSDIV2] =3D "vbusdiv2", ... ... [MT6370_CHAN_TEMP_JC] =3D "temp_jc", }; > > + "vbusdiv5", "vbusdiv2", "vsys", "vbat", > > + "ts_bat", "ibus", "ibat", "chg_vddp", > > + "temp_jc", > > +}; > > + > > +static int mt6370_adc_read_label(struct iio_dev *iio_dev, > > + struct iio_chan_spec const *chan, char *= label) > > +{ > > + return snprintf(label, PAGE_SIZE, "%s\n", > > + mt6370_channel_labels[chan->channel]); > > +} > > + > > +static const struct iio_info mt6370_adc_iio_info =3D { > > + .read_raw =3D mt6370_adc_read_raw, > > + .read_label =3D mt6370_adc_read_label, > > +}; > > + > > +#define MT6370_ADC_CHAN(_idx, _type, _addr) { \ > > + .type =3D _type, \ > > + .channel =3D MT6370_CHAN_##_idx, \ > > + .address =3D _addr, \ > > + .scan_index =3D MT6370_CHAN_##_idx, \ > > + .indexed =3D 1, \ > > + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ > > + BIT(IIO_CHAN_INFO_SCALE) | \ > > + BIT(IIO_CHAN_INFO_OFFSET), \ > > See above. Only temp_jc channel should hav an offset. > OK! > > +} > > + > > +static const struct iio_chan_spec mt6370_adc_channels[] =3D { > > + MT6370_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE, 1), > > + MT6370_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE, 2), > > + MT6370_ADC_CHAN(VSYS, IIO_VOLTAGE, 3), > > + MT6370_ADC_CHAN(VBAT, IIO_VOLTAGE, 4), > > + MT6370_ADC_CHAN(TS_BAT, IIO_VOLTAGE, 6), > > + MT6370_ADC_CHAN(IBUS, IIO_CURRENT, 8), > > + MT6370_ADC_CHAN(IBAT, IIO_CURRENT, 9), > > + MT6370_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE, 11), > > + MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12), > > +}; > > + > > +static int mt6370_adc_probe(struct platform_device *pdev) > > +{ > > + int ret; > > + struct mt6370_adc_data *priv; > > + struct regmap *regmap; > > + struct iio_dev *indio_dev; > > + > > + regmap =3D dev_get_regmap(pdev->dev.parent, NULL); > > + if (!regmap) { > > + dev_err(&pdev->dev, "Failed to get regmap\n"); > > + return -ENODEV; > > + } > > + > > + indio_dev =3D devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); > > + if (!indio_dev) > > + return -ENOMEM; > > + > > + priv =3D iio_priv(indio_dev); > > + priv->dev =3D &pdev->dev; > > + priv->regmap =3D regmap; > > + mutex_init(&priv->lock); > > + > > + ret =3D regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0); > > + if (ret) { > > + dev_err(&pdev->dev, "Failed to reset adc\n"); > > + return ret; > > + } > > + > > + indio_dev->name =3D dev_name(&pdev->dev); > > What does this end up as? It's used for userspace ABI and should > correspond to the part number, "mt6370-adc" probably > appropriate in this case (I think it'll end up as simply "adc.x" > currently?) Normally we just hard code this in the driver for > whatever devices the driver supports. I got it, I will change this name to "mt6370-adc" in the next version! Than= ks! > > > + indio_dev->info =3D &mt6370_adc_iio_info; > > + indio_dev->modes =3D INDIO_DIRECT_MODE; > > + indio_dev->channels =3D mt6370_adc_channels; > > + indio_dev->num_channels =3D ARRAY_SIZE(mt6370_adc_channels); > > + > > + return devm_iio_device_register(&pdev->dev, indio_dev); > > +} > > + > > +static const struct of_device_id mt6370_adc_of_id[] =3D { > > + { .compatible =3D "mediatek,mt6370-adc", }, > > + {} > > +}; > > +MODULE_DEVICE_TABLE(of, mt6370_adc_of_id); > > + > > +static struct platform_driver mt6370_adc_driver =3D { > > + .driver =3D { > > + .name =3D "mt6370-adc", > > + .of_match_table =3D mt6370_adc_of_id, > > + }, > > + .probe =3D mt6370_adc_probe, > > +}; > > +module_platform_driver(mt6370_adc_driver); > > + > > +MODULE_AUTHOR("ChiaEn Wu "); > > +MODULE_DESCRIPTION("MT6370 ADC Drvier"); > > +MODULE_LICENSE("GPL v2"); > Best regards, ChiaEn Wu