Re: [PATCH] iio: hid: Add temperature sensor support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2017-02-04 at 12:02 +0000, Jonathan Cameron wrote:
> On 04/02/17 13:47, Song Hongyan wrote:
> > 
> > Environmental temperature sensor is a hid defined sensor,
> > it measures temperature.
> > 
> > More information can be found in:
> > http://www.usb.org/developers/hidpage/HUTRR39b.pdf
> > 
> > According to IIO ABI definition, IIO_TEMP data output unit is
> > milli degrees Celsius. Add the unit convert from degree to milli
> > degree.
> > 
> > Signed-off-by: Song Hongyan <hongyan.song@xxxxxxxxx>
> A few bits and bobs inline.  Clearly I'll want Srinivas to comment on
> this
> one as well!


[...]

> 
+/* Capture samples in local storage */
> > +static int temperature_capture_sample(struct hid_sensor_hub_device
> > *hsdev,
> > +				unsigned int usage_id,
> > +				size_t raw_len, char *raw_data,
> > +				void *priv)
> > +{
> > +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
> Why not make priv the indio_dev directly? I would imagine it's the
> pdev
> passed in when registering the callbacks below.

Actually this priv can be renamed to pdev. The callback will be called
with platform_device * of the mfd device.

> > 
> > +	struct temperature_state *temperature_state =
> > iio_priv(indio_dev);
> > +
> > +	switch (usage_id) {
> > +	case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE:
> > +		temperature_state->temperature_data = *(s32
> > *)raw_data;
> > +		return 0;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +}
> > 

[...]

> > +/* Function to initialize the processing for usage id */
> > +static int hid_temperature_probe(struct platform_device *pdev)
> > +{
> > +	static const char *name = "temperature";
> > +	struct iio_dev *indio_dev;
> > +	struct temperature_state *temperature_state;
> > +	struct hid_sensor_hub_device *hsdev = pdev-
> > >dev.platform_data;
> > +	int ret;
> > +
> > +	indio_dev = devm_iio_device_alloc(&pdev->dev,
> > +				sizeof(struct temperature_state));
> > +	if (!indio_dev)
> > +		return -ENOMEM;
> > +
> > +	temperature_state = iio_priv(indio_dev);
> > +	temperature_state->common_attributes.hsdev = hsdev;
> > +	temperature_state->common_attributes.pdev = pdev;
> > +
> > +	ret = hid_sensor_parse_common_attributes(hsdev,
> > +					HID_USAGE_SENSOR_TEMPERATU
> > RE,
> > +					&temperature_state-
> > >common_attributes);
> > +	if (ret)
> > +		return ret;
> > +
> > +	indio_dev->channels = devm_kmemdup(&indio_dev->dev,
> > +					temperature_channels,
> > +					sizeof(temperature_channel
> > s),
> > +					GFP_KERNEL);
> > +	if (!indio_dev->channels)
> > +		return -ENOMEM;
> > +
> > +	ret = temperature_parse_report(pdev, hsdev,
> > +				(struct iio_chan_spec *)indio_dev-
> > >channels,
> > +				HID_USAGE_SENSOR_TEMPERATURE,
> > +				temperature_state);
> > +	if (ret)
> > +		return ret;
> > +
> > +	indio_dev->num_channels =
> > ARRAY_SIZE(temperature_channels);
> > +	indio_dev->dev.parent = &pdev->dev;
> > +	indio_dev->info = &temperature_info;
> > +	indio_dev->name = name;
> > +	indio_dev->modes = INDIO_DIRECT_MODE;
> > +
> > +	ret = iio_triggered_buffer_setup(indio_dev,
> > &iio_pollfunc_store_time,
> > +					NULL, NULL);
> > +	if (ret)
> > +		return ret;
> If you are going all devm (which is fine) then use
> devm_iio_triggered_buffer_setup.
> 
> > 
> > +
> > +	atomic_set(&temperature_state-
> > >common_attributes.data_ready, 0);
> > +	ret = hid_sensor_setup_trigger(indio_dev, name,
> > +				&temperature_state-
> > >common_attributes);
> I'd expect to see this unwound somewhere as well..

I missed this during my review. There has to be call
to  hid_sensor_remove_trigger() to do opposite.

> > 
> > +	if (ret)
> > +		goto error_unreg_buffer_funcs;
> > +
> > +	ret = devm_iio_device_register(indio_dev->dev.parent,
> > indio_dev);
> > +	if (ret)
> > +		goto error_unreg_buffer_funcs;
> Is there a race here in that userspace interfaces are exposed, but
> the
> hid system has no way to send answers to any queries?
Two scenarios possible:
- If somehow user space calls the raw read before the 
sensor_hub_register_callback() is called, then there should not be any
issue as the sensor_hub_input_attr_get_raw_value is called with
"SENSOR_HUB_SYNC" so wait till response arrives or timeout. So doesn't
depend on the callback.

- If user is activating the buffer mode before the callback us
registered, worst case it will miss event till the callback is
registered.

But we can call sensor_hub_register_callback()
before devm_iio_device_register(), but the we need to make sure that
the sensor_hub_remove_callback() is called
if devm_iio_device_register() fails.

> > 
> > +
> > +	platform_set_drvdata(pdev, indio_dev);
> > +
> > +	temperature_state->callbacks.send_event =
> > temperature_proc_event;
> > +	temperature_state->callbacks.capture_sample =
> > +						temperature_captur
> > e_sample;
> > +	temperature_state->callbacks.pdev = pdev;
> > +	ret = sensor_hub_register_callback(hsdev,
> > HID_USAGE_SENSOR_TEMPERATURE,
> > +					&temperature_state-
> > >callbacks); 
> > +	return ret;
> > +
> > +error_unreg_buffer_funcs:
> > +	iio_triggered_buffer_cleanup(indio_dev);
> > +	return ret;
> > +}
> > +
> > +/* Function to deinitialize the processing for usage id */
> > +static int hid_temperature_remove(struct platform_device *pdev)
> > +{
> > +	struct hid_sensor_hub_device *hsdev = pdev-
> > >dev.platform_data;
> > +
> > +	sensor_hub_remove_callback(hsdev,
> > HID_USAGE_SENSOR_TEMPERATURE);

hid_sensor_remove_trigger()

> > +
> > +	return 0;
> > +}
> > +
>
Thanks,
Srinivas��.n��������+%������w��{.n�����{��(��)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux