On Mon, 1 Jun 2015 19:06:52 +0530 Kishon Vijay Abraham I <kishon@xxxxxx> wrote: > Hi, > > On Thursday 16 April 2015 01:33 PM, NeilBrown wrote: > > From: NeilBrown <neilb@xxxxxxx> > > > > The twl4030 phy can measure, with low precision, the > > resistance-to-ground of the ID pin. > > > > Add a function to read the value, and export the result > > via sysfs. > > Little sceptical about adding new sysfs entries. Do you have a good reason to > add this? The hardware can report the value, so why not present it to user-space? I originally used this with a udev rule which would configure the maximum current based on the resistance measure - to work with the particular charger hardware I have. More recent patches try to do all of the max-current configuration in the kernel, so I could live without exporting the value via sysfs if that is a show-stopper. I can't see where the scepticism comes from though. It is a well defined and cleary documented feature of the hardware. Why not expose it? Thanks, NeilBrown > > Thanks > Kishon > > > > If the read fails, which it does sometimes, try again in 50msec. > > > > Acked-by: Pavel Machek <pavel@xxxxxx> > > Signed-off-by: NeilBrown <neilb@xxxxxxx> > > --- > > .../ABI/testing/sysfs-platform-twl4030-usb | 22 +++++++ > > drivers/phy/phy-twl4030-usb.c | 63 ++++++++++++++++++++ > > 2 files changed, 85 insertions(+) > > > > diff --git a/Documentation/ABI/testing/sysfs-platform-twl4030-usb b/Documentation/ABI/testing/sysfs-platform-twl4030-usb > > index 512c51be64ae..425d23676f8a 100644 > > --- a/Documentation/ABI/testing/sysfs-platform-twl4030-usb > > +++ b/Documentation/ABI/testing/sysfs-platform-twl4030-usb > > @@ -6,3 +6,25 @@ Description: > > Possible values: "on", "off". > > > > Changes are notified via select/poll. > > + > > +What: /sys/bus/platform/devices/*twl4030-usb/id > > +Description: > > + Read-only report on measurement of USB-OTG ID pin. > > + > > + The ID pin may be floating, grounded, or pulled to > > + ground by a resistor. > > + > > + A very course grained reading of the resistance is > > + available. The numbers given in kilo-ohms are roughly > > + the center-point of the detected range. > > + > > + Possible values are: > > + ground > > + 102k > > + 200k > > + 440k > > + floating > > + unknown > > + > > + "unknown" indicates a problem with trying to detect > > + the resistance. > > diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c > > index 3a707dd14238..1d6f3e70193e 100644 > > --- a/drivers/phy/phy-twl4030-usb.c > > +++ b/drivers/phy/phy-twl4030-usb.c > > @@ -379,6 +379,56 @@ static void twl4030_i2c_access(struct twl4030_usb *twl, int on) > > } > > } > > > > +enum twl4030_id_status { > > + TWL4030_GROUND, > > + TWL4030_102K, > > + TWL4030_200K, > > + TWL4030_440K, > > + TWL4030_FLOATING, > > + TWL4030_ID_UNKNOWN, > > +}; > > +static char *twl4030_id_names[] = { > > + "ground", > > + "102k", > > + "200k", > > + "440k", > > + "floating", > > + "unknown" > > +}; > > + > > +enum twl4030_id_status twl4030_get_id(struct twl4030_usb *twl) > > +{ > > + int ret; > > + > > + pm_runtime_get_sync(twl->dev); > > + if (twl->usb_mode == T2_USB_MODE_ULPI) > > + twl4030_i2c_access(twl, 1); > > + ret = twl4030_usb_read(twl, ULPI_OTG_CTRL); > > + if (ret < 0 || !(ret & ULPI_OTG_ID_PULLUP)) { > > + /* Need pull-up to read ID */ > > + twl4030_usb_set_bits(twl, ULPI_OTG_CTRL, > > + ULPI_OTG_ID_PULLUP); > > + mdelay(50); > > + } > > + ret = twl4030_usb_read(twl, ID_STATUS); > > + if (ret < 0 || (ret & 0x1f) == 0) { > > + mdelay(50); > > + ret = twl4030_usb_read(twl, ID_STATUS); > > + } > > + > > + if (twl->usb_mode == T2_USB_MODE_ULPI) > > + twl4030_i2c_access(twl, 0); > > + pm_runtime_put_autosuspend(twl->dev); > > + > > + if (ret < 0) > > + return TWL4030_ID_UNKNOWN; > > + ret = ffs(ret) - 1; > > + if (ret < TWL4030_GROUND || ret > TWL4030_FLOATING) > > + return TWL4030_ID_UNKNOWN; > > + > > + return ret; > > +} > > + > > static void __twl4030_phy_power(struct twl4030_usb *twl, int on) > > { > > u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); > > @@ -532,6 +582,16 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, > > } > > static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); > > > > +static ssize_t twl4030_usb_id_show(struct device *dev, > > + struct device_attribute *attr, > > + char *buf) > > +{ > > + struct twl4030_usb *twl = dev_get_drvdata(dev); > > + return scnprintf(buf, PAGE_SIZE, "%s\n", > > + twl4030_id_names[twl4030_get_id(twl)]); > > +} > > +static DEVICE_ATTR(id, 0444, twl4030_usb_id_show, NULL); > > + > > static irqreturn_t twl4030_usb_irq(int irq, void *_twl) > > { > > struct twl4030_usb *twl = _twl; > > @@ -709,6 +769,8 @@ static int twl4030_usb_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, twl); > > if (device_create_file(&pdev->dev, &dev_attr_vbus)) > > dev_warn(&pdev->dev, "could not create sysfs file\n"); > > + if (device_create_file(&pdev->dev, &dev_attr_id)) > > + dev_warn(&pdev->dev, "could not create sysfs file\n"); > > > > ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); > > > > @@ -753,6 +815,7 @@ static int twl4030_usb_remove(struct platform_device *pdev) > > pm_runtime_get_sync(twl->dev); > > cancel_delayed_work(&twl->id_workaround_work); > > device_remove_file(twl->dev, &dev_attr_vbus); > > + device_remove_file(twl->dev, &dev_attr_id); > > > > /* set transceiver mode to power on defaults */ > > twl4030_usb_set_mode(twl, -1); > > > >
Attachment:
pgpBqZPGjobdN.pgp
Description: OpenPGP digital signature