Re: [PATCH] hid_sensor_magn_3d: Fix scale for rotation from north channels

2015-07-19 Thread Reyad Attiyat
Thanks for the review. I don't believe many devices have this problem
no need to rush it.

On Sun, Jul 19, 2015 at 7:57 AM, Jonathan Cameron  wrote:
> On 15/07/15 08:43, Reyad Attiyat wrote:
>> Some devices on a hid sensor hub will not report a measurement unit. This
>> causes the rotation from north channels to have an incorrect scale value.
>> This patch will set the unit to degrees if the maximum value is 360 when
>> the unit exponent value is accounted for.
>>
>> Signed-off-by: Reyad Attiyat 
> Hmm. Ah well, another quirk to work around I guess.
>
> Looks fine to me.  Would like an Ack from Srinivas though.
> Also this is a bit large and invasive to send on as a fix (as it's not
> a regression) so will need to wait for the next merge window.
> Can mark it as stable material though so it will filter back through
> in the long run.
>
> If there are lots of devices being broken by this, let me know and maybe
> we will try and see if Greg is happy to pass it on to Linus.
>
> Jonathan
>
>> ---
>>  .../iio/common/hid-sensors/hid-sensor-attributes.c | 19 
>>  drivers/iio/magnetometer/hid-sensor-magn-3d.c  | 26 
>> +-
>>  include/linux/hid-sensor-hub.h |  4 
>>  3 files changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c 
>> b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>> index e81f434..3c79847 100644
>> --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>> +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>> @@ -46,6 +46,7 @@ static struct {
>>
>>   {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
>>   {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
>> + {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_DEGREES, 1, 0},
>>
>>   {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
>>   {HID_USAGE_SENSOR_INCLINOMETER_3D,
>> @@ -317,6 +318,24 @@ static void adjust_exponent_micro(int *val0, int *val1, 
>> int scale0,
>>   }
>>  }
>>
>> +void hid_sensor_get_unit_expo_fraction(
>> + struct hid_sensor_hub_attribute_info *attr_info,
>> + int *num, int *denom)
>> +{
>> + s32 exp = hid_sensor_convert_exponent(attr_info->unit_expo);
>> +
>> + if (exp == 0) {
>> + *num = *denom = 1;
>> + } else if (exp < 0) {
>> + *num = 1;
>> + *denom = pow_10(abs(exp));
>> + } else if (exp > 0) {
>> + *num = pow_10(exp);
>> + *denom = 1;
>> + }
>> +}
>> +EXPORT_SYMBOL(hid_sensor_get_unit_expo_fraction);
>> +
>>  int hid_sensor_format_scale(u32 usage_id,
>>   struct hid_sensor_hub_attribute_info *attr_info,
>>   int *val0, int *val1)
>> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
>> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> index d8a0c8d..173d2f5 100644
>> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> @@ -311,6 +311,7 @@ static int magn_3d_parse_report(struct platform_device 
>> *pdev,
>>   int i;
>>   int attr_count = 0;
>>   struct iio_chan_spec *_channels;
>> + struct hid_sensor_hub_attribute_info *first_channel_attr_info;
>>
>>   /* Scan for each usage attribute supported */
>>   for (i = 0; i < MAGN_3D_CHANNEL_MAX; i++) {
>> @@ -389,9 +390,32 @@ static int magn_3d_parse_report(struct platform_device 
>> *pdev,
>>   dev_dbg(>dev, "magn_3d Setup %d IIO channels\n",
>>   *chan_count);
>>
>> + first_channel_attr_info = &(st->magn[_channels[0].address]);
>> +
>> + /* Try and set unit based off exponent, logical min and max */
>> + if (!first_channel_attr_info->units) {
>> + int num, denom;
>> + s32 log_min = first_channel_attr_info->logical_minimum;
>> + s32 log_max = first_channel_attr_info->logical_maximum;
>> +
>> + dev_dbg(>dev, "magn_3d Units not set. Unit Expo %d 
>> Logical Min: %d Max: %d\n",
>> + first_channel_attr_info->unit_expo,
>> + log_min, log_max);
>> +
>> + hid_sensor_get_unit_expo_fraction(first_channel_attr_info,
>> + , );
>> +
>> + /* Ch

Re: [PATCH] hid_sensor_magn_3d: Fix scale for rotation from north channels

2015-07-19 Thread Reyad Attiyat
Thanks for the review. I don't believe many devices have this problem
no need to rush it.

On Sun, Jul 19, 2015 at 7:57 AM, Jonathan Cameron ji...@kernel.org wrote:
 On 15/07/15 08:43, Reyad Attiyat wrote:
 Some devices on a hid sensor hub will not report a measurement unit. This
 causes the rotation from north channels to have an incorrect scale value.
 This patch will set the unit to degrees if the maximum value is 360 when
 the unit exponent value is accounted for.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 Hmm. Ah well, another quirk to work around I guess.

 Looks fine to me.  Would like an Ack from Srinivas though.
 Also this is a bit large and invasive to send on as a fix (as it's not
 a regression) so will need to wait for the next merge window.
 Can mark it as stable material though so it will filter back through
 in the long run.

 If there are lots of devices being broken by this, let me know and maybe
 we will try and see if Greg is happy to pass it on to Linus.

 Jonathan

 ---
  .../iio/common/hid-sensors/hid-sensor-attributes.c | 19 
  drivers/iio/magnetometer/hid-sensor-magn-3d.c  | 26 
 +-
  include/linux/hid-sensor-hub.h |  4 
  3 files changed, 48 insertions(+), 1 deletion(-)

 diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c 
 b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
 index e81f434..3c79847 100644
 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
 +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
 @@ -46,6 +46,7 @@ static struct {

   {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
   {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
 + {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_DEGREES, 1, 0},

   {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
   {HID_USAGE_SENSOR_INCLINOMETER_3D,
 @@ -317,6 +318,24 @@ static void adjust_exponent_micro(int *val0, int *val1, 
 int scale0,
   }
  }

 +void hid_sensor_get_unit_expo_fraction(
 + struct hid_sensor_hub_attribute_info *attr_info,
 + int *num, int *denom)
 +{
 + s32 exp = hid_sensor_convert_exponent(attr_info-unit_expo);
 +
 + if (exp == 0) {
 + *num = *denom = 1;
 + } else if (exp  0) {
 + *num = 1;
 + *denom = pow_10(abs(exp));
 + } else if (exp  0) {
 + *num = pow_10(exp);
 + *denom = 1;
 + }
 +}
 +EXPORT_SYMBOL(hid_sensor_get_unit_expo_fraction);
 +
  int hid_sensor_format_scale(u32 usage_id,
   struct hid_sensor_hub_attribute_info *attr_info,
   int *val0, int *val1)
 diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
 b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 index d8a0c8d..173d2f5 100644
 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 @@ -311,6 +311,7 @@ static int magn_3d_parse_report(struct platform_device 
 *pdev,
   int i;
   int attr_count = 0;
   struct iio_chan_spec *_channels;
 + struct hid_sensor_hub_attribute_info *first_channel_attr_info;

   /* Scan for each usage attribute supported */
   for (i = 0; i  MAGN_3D_CHANNEL_MAX; i++) {
 @@ -389,9 +390,32 @@ static int magn_3d_parse_report(struct platform_device 
 *pdev,
   dev_dbg(pdev-dev, magn_3d Setup %d IIO channels\n,
   *chan_count);

 + first_channel_attr_info = (st-magn[_channels[0].address]);
 +
 + /* Try and set unit based off exponent, logical min and max */
 + if (!first_channel_attr_info-units) {
 + int num, denom;
 + s32 log_min = first_channel_attr_info-logical_minimum;
 + s32 log_max = first_channel_attr_info-logical_maximum;
 +
 + dev_dbg(pdev-dev, magn_3d Units not set. Unit Expo %d 
 Logical Min: %d Max: %d\n,
 + first_channel_attr_info-unit_expo,
 + log_min, log_max);
 +
 + hid_sensor_get_unit_expo_fraction(first_channel_attr_info,
 + num, denom);
 +
 + /* Check for unit Degrees */
 + if (log_min == 0  num == 1  (log_max == 360 * denom)) {
 + first_channel_attr_info-units =
 + HID_USAGE_SENSOR_UNITS_DEGREES;
 + dev_dbg(pdev-dev, magn_3d Set units to degrees.);
 + }
 +
 + }
   st-scale_precision = hid_sensor_format_scale(
   HID_USAGE_SENSOR_COMPASS_3D,
 - st-magn[CHANNEL_SCAN_INDEX_X],
 + first_channel_attr_info,
   st-scale_pre_decml, st-scale_post_decml);

   /* Set Sensitivity field ids, when there is no individual modifier */
 diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor

[PATCH] hid_sensor_magn_3d: Fix scale for rotation from north channels

2015-07-15 Thread Reyad Attiyat
Some devices on a hid sensor hub will not report a measurement unit. This
causes the rotation from north channels to have an incorrect scale value.
This patch will set the unit to degrees if the maximum value is 360 when
the unit exponent value is accounted for.

Signed-off-by: Reyad Attiyat 
---
 .../iio/common/hid-sensors/hid-sensor-attributes.c | 19 
 drivers/iio/magnetometer/hid-sensor-magn-3d.c  | 26 +-
 include/linux/hid-sensor-hub.h |  4 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c 
b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index e81f434..3c79847 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -46,6 +46,7 @@ static struct {
 
{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
{HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
+   {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_DEGREES, 1, 0},
 
{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
{HID_USAGE_SENSOR_INCLINOMETER_3D,
@@ -317,6 +318,24 @@ static void adjust_exponent_micro(int *val0, int *val1, 
int scale0,
}
 }
 
+void hid_sensor_get_unit_expo_fraction(
+   struct hid_sensor_hub_attribute_info *attr_info,
+   int *num, int *denom)
+{
+   s32 exp = hid_sensor_convert_exponent(attr_info->unit_expo);
+
+   if (exp == 0) {
+   *num = *denom = 1;
+   } else if (exp < 0) {
+   *num = 1;
+   *denom = pow_10(abs(exp));
+   } else if (exp > 0) {
+   *num = pow_10(exp);
+   *denom = 1;
+   }
+}
+EXPORT_SYMBOL(hid_sensor_get_unit_expo_fraction);
+
 int hid_sensor_format_scale(u32 usage_id,
struct hid_sensor_hub_attribute_info *attr_info,
int *val0, int *val1)
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index d8a0c8d..173d2f5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -311,6 +311,7 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
int i;
int attr_count = 0;
struct iio_chan_spec *_channels;
+   struct hid_sensor_hub_attribute_info *first_channel_attr_info;
 
/* Scan for each usage attribute supported */
for (i = 0; i < MAGN_3D_CHANNEL_MAX; i++) {
@@ -389,9 +390,32 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
dev_dbg(>dev, "magn_3d Setup %d IIO channels\n",
*chan_count);
 
+   first_channel_attr_info = &(st->magn[_channels[0].address]);
+
+   /* Try and set unit based off exponent, logical min and max */
+   if (!first_channel_attr_info->units) {
+   int num, denom;
+   s32 log_min = first_channel_attr_info->logical_minimum;
+   s32 log_max = first_channel_attr_info->logical_maximum;
+
+   dev_dbg(>dev, "magn_3d Units not set. Unit Expo %d 
Logical Min: %d Max: %d\n",
+   first_channel_attr_info->unit_expo,
+   log_min, log_max);
+
+   hid_sensor_get_unit_expo_fraction(first_channel_attr_info,
+   , );
+
+   /* Check for unit Degrees */
+   if (log_min == 0 && num == 1 && (log_max == 360 * denom)) {
+   first_channel_attr_info->units =
+   HID_USAGE_SENSOR_UNITS_DEGREES;
+   dev_dbg(>dev, "magn_3d Set units to degrees.");
+   }
+
+   }
st->scale_precision = hid_sensor_format_scale(
HID_USAGE_SENSOR_COMPASS_3D,
-   >magn[CHANNEL_SCAN_INDEX_X],
+   first_channel_attr_info,
>scale_pre_decml, >scale_post_decml);
 
/* Set Sensitivity field ids, when there is no individual modifier */
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index 0042bf3..627fd68 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -267,6 +267,10 @@ int hid_sensor_format_scale(u32 usage_id,
struct hid_sensor_hub_attribute_info *attr_info,
int *val0, int *val1);
 
+void hid_sensor_get_unit_expo_fraction(
+   struct hid_sensor_hub_attribute_info *attr_info,
+   int *num, int *denom);
+
 s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
 
 #endif
-- 
2.4.3

--
To unsubscribe from this list: send the line

[PATCH] hid_sensor_magn_3d: Fix scale for rotation from north channels

2015-07-15 Thread Reyad Attiyat
Some devices on a hid sensor hub will not report a measurement unit. This
causes the rotation from north channels to have an incorrect scale value.
This patch will set the unit to degrees if the maximum value is 360 when
the unit exponent value is accounted for.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 .../iio/common/hid-sensors/hid-sensor-attributes.c | 19 
 drivers/iio/magnetometer/hid-sensor-magn-3d.c  | 26 +-
 include/linux/hid-sensor-hub.h |  4 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c 
b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index e81f434..3c79847 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -46,6 +46,7 @@ static struct {
 
{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
{HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
+   {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_DEGREES, 1, 0},
 
{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
{HID_USAGE_SENSOR_INCLINOMETER_3D,
@@ -317,6 +318,24 @@ static void adjust_exponent_micro(int *val0, int *val1, 
int scale0,
}
 }
 
+void hid_sensor_get_unit_expo_fraction(
+   struct hid_sensor_hub_attribute_info *attr_info,
+   int *num, int *denom)
+{
+   s32 exp = hid_sensor_convert_exponent(attr_info-unit_expo);
+
+   if (exp == 0) {
+   *num = *denom = 1;
+   } else if (exp  0) {
+   *num = 1;
+   *denom = pow_10(abs(exp));
+   } else if (exp  0) {
+   *num = pow_10(exp);
+   *denom = 1;
+   }
+}
+EXPORT_SYMBOL(hid_sensor_get_unit_expo_fraction);
+
 int hid_sensor_format_scale(u32 usage_id,
struct hid_sensor_hub_attribute_info *attr_info,
int *val0, int *val1)
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index d8a0c8d..173d2f5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -311,6 +311,7 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
int i;
int attr_count = 0;
struct iio_chan_spec *_channels;
+   struct hid_sensor_hub_attribute_info *first_channel_attr_info;
 
/* Scan for each usage attribute supported */
for (i = 0; i  MAGN_3D_CHANNEL_MAX; i++) {
@@ -389,9 +390,32 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
dev_dbg(pdev-dev, magn_3d Setup %d IIO channels\n,
*chan_count);
 
+   first_channel_attr_info = (st-magn[_channels[0].address]);
+
+   /* Try and set unit based off exponent, logical min and max */
+   if (!first_channel_attr_info-units) {
+   int num, denom;
+   s32 log_min = first_channel_attr_info-logical_minimum;
+   s32 log_max = first_channel_attr_info-logical_maximum;
+
+   dev_dbg(pdev-dev, magn_3d Units not set. Unit Expo %d 
Logical Min: %d Max: %d\n,
+   first_channel_attr_info-unit_expo,
+   log_min, log_max);
+
+   hid_sensor_get_unit_expo_fraction(first_channel_attr_info,
+   num, denom);
+
+   /* Check for unit Degrees */
+   if (log_min == 0  num == 1  (log_max == 360 * denom)) {
+   first_channel_attr_info-units =
+   HID_USAGE_SENSOR_UNITS_DEGREES;
+   dev_dbg(pdev-dev, magn_3d Set units to degrees.);
+   }
+
+   }
st-scale_precision = hid_sensor_format_scale(
HID_USAGE_SENSOR_COMPASS_3D,
-   st-magn[CHANNEL_SCAN_INDEX_X],
+   first_channel_attr_info,
st-scale_pre_decml, st-scale_post_decml);
 
/* Set Sensitivity field ids, when there is no individual modifier */
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index 0042bf3..627fd68 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -267,6 +267,10 @@ int hid_sensor_format_scale(u32 usage_id,
struct hid_sensor_hub_attribute_info *attr_info,
int *val0, int *val1);
 
+void hid_sensor_get_unit_expo_fraction(
+   struct hid_sensor_hub_attribute_info *attr_info,
+   int *num, int *denom);
+
 s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
 
 #endif
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org

Re: [PATCH v3] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-07-02 Thread Reyad Attiyat
This version of the patch changes last_trb varible name to
last_trb_num and fixes code style. I have also added a td to the urb
td array. This now gets prepared properl,y with prepare_transfer(),
and is handled correctly when transferred and completed. It only calls
the urb completion callback once as there is a check in finish_td() to
ensure that all td's have been received.

If you think I should change anything else please let me know.

Thank you,
Reyad Attiyat

On Thu, Jul 2, 2015 at 1:54 PM, Reyad Attiyat  wrote:
> This commit checks for the URB_ZERO_PACKET flag and creates an extra
> zero-length td if the urb transfer length is a multiple of the endpoint's
> max packet length.
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/usb/host/xhci-ring.c | 66 
> ++--
>  drivers/usb/host/xhci.c  |  5 
>  2 files changed, 57 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 7d34cbf..31ea1b9 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -3038,9 +3038,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> struct xhci_td *td;
> struct scatterlist *sg;
> int num_sgs;
> -   int trb_buff_len, this_sg_len, running_total;
> +   int trb_buff_len, this_sg_len, running_total, ret;
> unsigned int total_packet_count;
> +   bool zero_length_needed;
> bool first_trb;
> +   int last_trb_num;
> u64 addr;
> bool more_trbs_coming;
>
> @@ -3056,13 +3058,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
> usb_endpoint_maxp(>ep->desc));
>
> -   trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
> +   ret = prepare_transfer(xhci, xhci->devs[slot_id],
> ep_index, urb->stream_id,
> num_trbs, urb, 0, mem_flags);
> -   if (trb_buff_len < 0)
> -   return trb_buff_len;
> +   if (ret < 0)
> +   return ret;
>
> urb_priv = urb->hcpriv;
> +
> +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
> +   zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
> +   urb_priv->length == 2;
> +   if (zero_length_needed) {
> +   num_trbs++;
> +   xhci_dbg(xhci, "Creating zero length td.\n");
> +   ret = prepare_transfer(xhci, xhci->devs[slot_id],
> +   ep_index, urb->stream_id,
> +   1, urb, 1, mem_flags);
> +   if (ret < 0)
> +   return ret;
> +   }
> +
> td = urb_priv->td[0];
>
> /*
> @@ -3092,6 +3108,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> trb_buff_len = urb->transfer_buffer_length;
>
> first_trb = true;
> +   last_trb_num = zero_length_needed ? 2 : 1;
> /* Queue the first TRB, even if it's zero-length */
> do {
> u32 field = 0;
> @@ -3109,12 +3126,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> /* Chain all the TRBs together; clear the chain bit in the 
> last
>  * TRB to indicate it's the last TRB in the chain.
>  */
> -   if (num_trbs > 1) {
> +   if (num_trbs > last_trb_num) {
> field |= TRB_CHAIN;
> -   } else {
> -   /* FIXME - add check for ZERO_PACKET flag before this 
> */
> +   } else if (num_trbs == last_trb_num) {
> td->last_trb = ep_ring->enqueue;
> field |= TRB_IOC;
> +   } else if (zero_length_needed && num_trbs == 1) {
> +   trb_buff_len = 0;
> +   urb_priv->td[1]->last_trb = ep_ring->enqueue;
> +   field |= TRB_IOC;
> }
>
> /* Only set interrupt on short packet for IN endpoints */
> @@ -3176,7 +3196,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> if (running_total + trb_buff_len > 
> urb->transfer_buffer_length)
> trb_buff_len =
> urb->transfer_buffer_length - running_total;
> -   } while (running_total < urb->transfer_buffer_length);
> +  

[PATCH v3] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-07-02 Thread Reyad Attiyat
This commit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint's
max packet length.

Signed-off-by: Reyad Attiyat 
---
 drivers/usb/host/xhci-ring.c | 66 ++--
 drivers/usb/host/xhci.c  |  5 
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..31ea1b9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3038,9 +3038,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
struct xhci_td *td;
struct scatterlist *sg;
int num_sgs;
-   int trb_buff_len, this_sg_len, running_total;
+   int trb_buff_len, this_sg_len, running_total, ret;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb_num;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,13 +3058,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(>ep->desc));
 
-   trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
+   ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
num_trbs, urb, 0, mem_flags);
-   if (trb_buff_len < 0)
-   return trb_buff_len;
+   if (ret < 0)
+   return ret;
 
urb_priv = urb->hcpriv;
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
+   urb_priv->length == 2;
+   if (zero_length_needed) {
+   num_trbs++;
+   xhci_dbg(xhci, "Creating zero length td.\n");
+   ret = prepare_transfer(xhci, xhci->devs[slot_id],
+   ep_index, urb->stream_id,
+   1, urb, 1, mem_flags);
+   if (ret < 0)
+   return ret;
+   }
+
td = urb_priv->td[0];
 
/*
@@ -3092,6 +3108,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb->transfer_buffer_length;
 
first_trb = true;
+   last_trb_num = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3126,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs > 1) {
+   if (num_trbs > last_trb_num) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb_num) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed && num_trbs == 1) {
+   trb_buff_len = 0;
+   urb_priv->td[1]->last_trb = ep_ring->enqueue;
+   field |= TRB_IOC;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3176,7 +3196,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
if (running_total + trb_buff_len > urb->transfer_buffer_length)
trb_buff_len =
urb->transfer_buffer_length - running_total;
-   } while (running_total < urb->transfer_buffer_length);
+   } while (num_trbs > 0);
 
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3194,7 +3214,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb_num;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3247,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
 
ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
@@ -3234,6 +3255,20 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
return ret;
 
urb_priv = urb->hcpriv;
+
+   /* Deal with URB_ZER

[PATCH v3] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-07-02 Thread Reyad Attiyat
This commit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint's
max packet length.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 66 ++--
 drivers/usb/host/xhci.c  |  5 
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..31ea1b9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3038,9 +3038,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
struct xhci_td *td;
struct scatterlist *sg;
int num_sgs;
-   int trb_buff_len, this_sg_len, running_total;
+   int trb_buff_len, this_sg_len, running_total, ret;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb_num;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,13 +3058,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
usb_endpoint_maxp(urb-ep-desc));
 
-   trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
+   ret = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
num_trbs, urb, 0, mem_flags);
-   if (trb_buff_len  0)
-   return trb_buff_len;
+   if (ret  0)
+   return ret;
 
urb_priv = urb-hcpriv;
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = urb-transfer_flags  URB_ZERO_PACKET 
+   urb_priv-length == 2;
+   if (zero_length_needed) {
+   num_trbs++;
+   xhci_dbg(xhci, Creating zero length td.\n);
+   ret = prepare_transfer(xhci, xhci-devs[slot_id],
+   ep_index, urb-stream_id,
+   1, urb, 1, mem_flags);
+   if (ret  0)
+   return ret;
+   }
+
td = urb_priv-td[0];
 
/*
@@ -3092,6 +3108,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb-transfer_buffer_length;
 
first_trb = true;
+   last_trb_num = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3126,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs  1) {
+   if (num_trbs  last_trb_num) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb_num) {
td-last_trb = ep_ring-enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed  num_trbs == 1) {
+   trb_buff_len = 0;
+   urb_priv-td[1]-last_trb = ep_ring-enqueue;
+   field |= TRB_IOC;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3176,7 +3196,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
if (running_total + trb_buff_len  urb-transfer_buffer_length)
trb_buff_len =
urb-transfer_buffer_length - running_total;
-   } while (running_total  urb-transfer_buffer_length);
+   } while (num_trbs  0);
 
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb-stream_id,
@@ -3194,7 +3214,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb_num;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3247,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
 
ret = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
@@ -3234,6 +3255,20 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
return ret;
 
urb_priv = urb-hcpriv;
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = urb-transfer_flags  URB_ZERO_PACKET 
+   urb_priv-length == 2

Re: [PATCH v3] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-07-02 Thread Reyad Attiyat
This version of the patch changes last_trb varible name to
last_trb_num and fixes code style. I have also added a td to the urb
td array. This now gets prepared properl,y with prepare_transfer(),
and is handled correctly when transferred and completed. It only calls
the urb completion callback once as there is a check in finish_td() to
ensure that all td's have been received.

If you think I should change anything else please let me know.

Thank you,
Reyad Attiyat

On Thu, Jul 2, 2015 at 1:54 PM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 This commit checks for the URB_ZERO_PACKET flag and creates an extra
 zero-length td if the urb transfer length is a multiple of the endpoint's
 max packet length.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/usb/host/xhci-ring.c | 66 
 ++--
  drivers/usb/host/xhci.c  |  5 
  2 files changed, 57 insertions(+), 14 deletions(-)

 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index 7d34cbf..31ea1b9 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -3038,9 +3038,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 struct xhci_td *td;
 struct scatterlist *sg;
 int num_sgs;
 -   int trb_buff_len, this_sg_len, running_total;
 +   int trb_buff_len, this_sg_len, running_total, ret;
 unsigned int total_packet_count;
 +   bool zero_length_needed;
 bool first_trb;
 +   int last_trb_num;
 u64 addr;
 bool more_trbs_coming;

 @@ -3056,13 +3058,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
 usb_endpoint_maxp(urb-ep-desc));

 -   trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
 +   ret = prepare_transfer(xhci, xhci-devs[slot_id],
 ep_index, urb-stream_id,
 num_trbs, urb, 0, mem_flags);
 -   if (trb_buff_len  0)
 -   return trb_buff_len;
 +   if (ret  0)
 +   return ret;

 urb_priv = urb-hcpriv;
 +
 +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
 +   zero_length_needed = urb-transfer_flags  URB_ZERO_PACKET 
 +   urb_priv-length == 2;
 +   if (zero_length_needed) {
 +   num_trbs++;
 +   xhci_dbg(xhci, Creating zero length td.\n);
 +   ret = prepare_transfer(xhci, xhci-devs[slot_id],
 +   ep_index, urb-stream_id,
 +   1, urb, 1, mem_flags);
 +   if (ret  0)
 +   return ret;
 +   }
 +
 td = urb_priv-td[0];

 /*
 @@ -3092,6 +3108,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 trb_buff_len = urb-transfer_buffer_length;

 first_trb = true;
 +   last_trb_num = zero_length_needed ? 2 : 1;
 /* Queue the first TRB, even if it's zero-length */
 do {
 u32 field = 0;
 @@ -3109,12 +3126,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 /* Chain all the TRBs together; clear the chain bit in the 
 last
  * TRB to indicate it's the last TRB in the chain.
  */
 -   if (num_trbs  1) {
 +   if (num_trbs  last_trb_num) {
 field |= TRB_CHAIN;
 -   } else {
 -   /* FIXME - add check for ZERO_PACKET flag before this 
 */
 +   } else if (num_trbs == last_trb_num) {
 td-last_trb = ep_ring-enqueue;
 field |= TRB_IOC;
 +   } else if (zero_length_needed  num_trbs == 1) {
 +   trb_buff_len = 0;
 +   urb_priv-td[1]-last_trb = ep_ring-enqueue;
 +   field |= TRB_IOC;
 }

 /* Only set interrupt on short packet for IN endpoints */
 @@ -3176,7 +3196,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 if (running_total + trb_buff_len  
 urb-transfer_buffer_length)
 trb_buff_len =
 urb-transfer_buffer_length - running_total;
 -   } while (running_total  urb-transfer_buffer_length);
 +   } while (num_trbs  0);

 check_trb_math(urb, num_trbs, running_total);
 giveback_first_trb(xhci, slot_id, ep_index, urb-stream_id,
 @@ -3194,7 +3214,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
 mem_flags,
 int num_trbs;
 struct xhci_generic_trb *start_trb;
 bool first_trb;
 +   int last_trb_num;
 bool more_trbs_coming;
 +   bool zero_length_needed;
 int start_cycle;
 u32 field, length_field;

 @@ -3225,7 +3247,6 @@ int

Re: [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-29 Thread Reyad Attiyat
Hey Mathias,

The intention is to send an extra endpoint packet of length zero as my
wireless card needs this to function properly. I have skimmed through
the xhci spec and assumed that each td would generate a packet. That
is why I do not chain the last trb or add a interrupt flag, since I
don't want to call the urb completion function called twice or called
with the incorrect td or length.

I have since tried a patch that just chains the trbs together, with
the zero-length trb, and this still creates a zero-length packet. I
was thinking I could remove the use of the last_trb variable I was
using and simply chain all the trbs together and place the interupt
flag on the zero-length trb if it exsits. Also I noticed that the
other host controller drivers (ehci and ohci) check to ensure that the
endpoint is sending data out and that the urb length is greater than
zero. I will add these checks as well to keep in line with the their
implementation.

Do you think this is the best method for creating a zero-length
packet, will every trb convert into at least one endpoint packet?

Thank you,
Reyad Attiyat



On Mon, Jun 29, 2015 at 10:48 AM, Mathias Nyman  wrote:
> Hi
>
> On 29.06.2015 03:53, Reyad Attiyat wrote:
>> This commmit checks for the URB_ZERO_PACKET flag and creates an extra
>> zero-length td if the urb transfer length is a multiple of the endpoint's
>> max packet length.
>>
>> Signed-off-by: Reyad Attiyat 
>> ---
>
> Thanks for the patch.
> Generic idea and implementation looks good, there are some opens though
> See comments and questions inline.
>
>>  drivers/usb/host/xhci-ring.c | 43 
>> +--
>>  1 file changed, 33 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
>> index 7d34cbf..3d57a7a 100644
>> --- a/drivers/usb/host/xhci-ring.c
>> +++ b/drivers/usb/host/xhci-ring.c
>> @@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
>> gfp_t mem_flags,
>>   int num_sgs;
>>   int trb_buff_len, this_sg_len, running_total;
>>   unsigned int total_packet_count;
>> + bool zero_length_needed;
>>   bool first_trb;
>> + int last_trb;
>
> last_trb isn't a really a good name as it might be confused with td->last_trb.
> It's used for different purposes here.
>
>>   u64 addr;
>>   bool more_trbs_coming;
>>
>> @@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
>> gfp_t mem_flags,
>>   total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
>>   usb_endpoint_maxp(>ep->desc));
>>
>> + /* Deal with URB_ZERO_PACKET - need one more td/trb */
>> + zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
>> +  && !(urb->transfer_buffer_length % usb_endpoint_maxp(>ep->desc));
>
> Please move the "&&" to end of previous line.
> (minor thing but helps readability)
>
> Checkpatch also complains about missing whitespaces in the if () statements.
>
>> + if(zero_length_needed){
>> + num_trbs++;
>> + xhci_dbg(xhci, "Creating zero length td.\n");
>> + }
>> +
>>   trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
>>   ep_index, urb->stream_id,
>>   num_trbs, urb, 0, mem_flags);
>> @@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
>> gfp_t mem_flags,
>>   trb_buff_len = urb->transfer_buffer_length;
>>
>>   first_trb = true;
>> + last_trb = zero_length_needed ? 2 : 1;
>>   /* Queue the first TRB, even if it's zero-length */
>>   do {
>>   u32 field = 0;
>> @@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
>> gfp_t mem_flags,
>>   /* Chain all the TRBs together; clear the chain bit in the last
>>* TRB to indicate it's the last TRB in the chain.
>>*/
>> - if (num_trbs > 1) {
>> + if (num_trbs > last_trb) {
>>   field |= TRB_CHAIN;
>> - } else {
>> - /* FIXME - add check for ZERO_PACKET flag before this 
>> */
>> + } else if (num_trbs == last_trb) {
>>   td->last_trb = ep_ring->enqueue;
>>   field |= TRB_IOC;
>> + } else if (zero_length_needed && num_trbs == 1) {
>> + trb_buff_len = 0;
>>  

Re: [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-29 Thread Reyad Attiyat
Hey Mathias,

The intention is to send an extra endpoint packet of length zero as my
wireless card needs this to function properly. I have skimmed through
the xhci spec and assumed that each td would generate a packet. That
is why I do not chain the last trb or add a interrupt flag, since I
don't want to call the urb completion function called twice or called
with the incorrect td or length.

I have since tried a patch that just chains the trbs together, with
the zero-length trb, and this still creates a zero-length packet. I
was thinking I could remove the use of the last_trb variable I was
using and simply chain all the trbs together and place the interupt
flag on the zero-length trb if it exsits. Also I noticed that the
other host controller drivers (ehci and ohci) check to ensure that the
endpoint is sending data out and that the urb length is greater than
zero. I will add these checks as well to keep in line with the their
implementation.

Do you think this is the best method for creating a zero-length
packet, will every trb convert into at least one endpoint packet?

Thank you,
Reyad Attiyat



On Mon, Jun 29, 2015 at 10:48 AM, Mathias Nyman mathias.ny...@intel.com wrote:
 Hi

 On 29.06.2015 03:53, Reyad Attiyat wrote:
 This commmit checks for the URB_ZERO_PACKET flag and creates an extra
 zero-length td if the urb transfer length is a multiple of the endpoint's
 max packet length.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---

 Thanks for the patch.
 Generic idea and implementation looks good, there are some opens though
 See comments and questions inline.

  drivers/usb/host/xhci-ring.c | 43 
 +--
  1 file changed, 33 insertions(+), 10 deletions(-)

 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index 7d34cbf..3d57a7a 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
   int num_sgs;
   int trb_buff_len, this_sg_len, running_total;
   unsigned int total_packet_count;
 + bool zero_length_needed;
   bool first_trb;
 + int last_trb;

 last_trb isn't a really a good name as it might be confused with td-last_trb.
 It's used for different purposes here.

   u64 addr;
   bool more_trbs_coming;

 @@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
   total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
   usb_endpoint_maxp(urb-ep-desc));

 + /* Deal with URB_ZERO_PACKET - need one more td/trb */
 + zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
 +   !(urb-transfer_buffer_length % usb_endpoint_maxp(urb-ep-desc));

 Please move the  to end of previous line.
 (minor thing but helps readability)

 Checkpatch also complains about missing whitespaces in the if () statements.

 + if(zero_length_needed){
 + num_trbs++;
 + xhci_dbg(xhci, Creating zero length td.\n);
 + }
 +
   trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
   ep_index, urb-stream_id,
   num_trbs, urb, 0, mem_flags);
 @@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
   trb_buff_len = urb-transfer_buffer_length;

   first_trb = true;
 + last_trb = zero_length_needed ? 2 : 1;
   /* Queue the first TRB, even if it's zero-length */
   do {
   u32 field = 0;
 @@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
   /* Chain all the TRBs together; clear the chain bit in the last
* TRB to indicate it's the last TRB in the chain.
*/
 - if (num_trbs  1) {
 + if (num_trbs  last_trb) {
   field |= TRB_CHAIN;
 - } else {
 - /* FIXME - add check for ZERO_PACKET flag before this 
 */
 + } else if (num_trbs == last_trb) {
   td-last_trb = ep_ring-enqueue;
   field |= TRB_IOC;
 + } else if (zero_length_needed  num_trbs == 1) {
 + trb_buff_len = 0;
   }

 Normally chain bits are set for all TRBs except the last TRB, and the IOC 
 (interrupt on completion)
 is usually set for only the last TRB.

 In case last_trb == 2, the chain bit is now not set between the TRB 
 containing the last data
 and the actual last zero TRB, which is the last TRB in the TD.
 It now also sets the interrupt on completion (IOC) for the TRB with the last 
 data,
 but not for the final last, zero lengt TRB in the TD.

 Is this intentional and how we want zero packet bulk transfers to behave?

 -Mathias



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo

[PATCH] mwifiex: usb: Fix double add error when submitting rx urb

2015-06-28 Thread Reyad Attiyat
There is an error that can occur where the driver adds the same URB to USB 
submission list twice.
This happens since mwifiex_usb_submit_rem_rx can submit packets at same time as 
an rx urb complete callback.
This causes list corruption and is fixed by not setting the skb to NULL when 
submitting an rx packet.

[   84.461242] WARNING: CPU: 1 PID: 748 at lib/list_debug.c:36 
__list_add+0xcb/0xd0()
[   84.461245] list_add double add: new=8800c92b0c50, 
prev=8800c92b0c50, next=8800ced6c430.
[   84.461247] Modules linked in: rfcomm fuse cmac nf_conntrack_netbios_ns 
nf_conntrack_broadcast ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack 
ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat 
nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security 
ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 
nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bnep iptable_mangle 
iptable_security iptable_raw btusb btintel bluetooth mwifiex_usb mwifiex 
x86_pkg_temp_thermal cfg80211 coretemp r8712u(C) kvm_intel kvm hid_sensor_als 
hid_sensor_incl_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_accel_3d 
hid_sensor_gyro_3d hid_sensor_trigger hid_sensor_iio_common 
industrialio_triggered_buffer kfifo_buf rfkill iTCO_wdt industrialio 
iTCO_vendor_support
[   84.461316]  crc32_pclmul crc32c_intel ghash_clmulni_intel microcode 
snd_hda_codec_realtek vfat snd_hda_codec_generic fat snd_hda_codec_hdmi 
snd_hda_intel snd_hda_controller uvcvideo snd_hda_codec videobuf2_vmalloc 
videobuf2_memops snd_hwdep videobuf2_core snd_hda_core joydev v4l2_common 
videodev hid_sensor_hub snd_seq hid_multitouch media snd_seq_device snd_pcm 
snd_timer mei_me snd i2c_i801 lpc_ich mei soundcore tpm_infineon tpm_tis tpm 
i2c_hid i2c_designware_platform i2c_designware_core nfsd auth_rpcgss nfs_acl 
lockd grace sunrpc sch_fq_codel i915 i2c_algo_bit drm_kms_helper drm xhci_pci 
xhci_hcd ehci_pci sd_mod ehci_hcd video
[   84.461383] CPU: 1 PID: 748 Comm: kworker/u9:0 Tainted: G C  
4.1.0-rc5+ #163
[   84.461386] Hardware name: Microsoft Corporation Surface Pro 2/Surface Pro 
2, BIOS 2.05.0250 04/10/2015
[   84.461396] Workqueue: MWIFIEX_RX_WORK_QUEUE mwifiex_rx_work_queue [mwifiex]
[   84.461399]  81a8150e 8801174cf8e8 817df830 

[   84.461405]  8801174cf938 8801174cf928 810a54ba 
8800c86bd750
[   84.461410]  8800c92b0c50 8800c92b0c50 8800ced6c430 
88010c057178
[   84.461416] Call Trace:
[   84.461421]  [] dump_stack+0x4f/0x7b
[   84.461428]  [] warn_slowpath_common+0x8a/0xc0
[   84.461432]  [] warn_slowpath_fmt+0x46/0x50
[   84.461436]  [] __list_add+0xcb/0xd0
[   84.461442]  [] ? usb_hcd_link_urb_to_ep+0x2a/0xa0
[   84.461446]  [] usb_hcd_link_urb_to_ep+0x80/0xa0
[   84.461459]  [] prepare_transfer+0xaa/0x130 [xhci_hcd]
[   84.461470]  [] xhci_queue_bulk_tx+0xb7/0x7a0 [xhci_hcd]
[   84.461480]  [] ? xhci_urb_enqueue+0x50f/0x660 [xhci_hcd]
[   84.461489]  [] ? xhci_urb_enqueue+0x50f/0x660 [xhci_hcd]
[   84.461498]  [] xhci_urb_enqueue+0x5c5/0x660 [xhci_hcd]
[   84.461503]  [] usb_hcd_submit_urb+0x93/0xa70
[   84.461507]  [] ? __alloc_skb+0x78/0x1f0
[   84.461511]  [] ? __kmalloc_reserve.isra.26+0x31/0x90
[   84.461515]  [] ? __alloc_skb+0x4c/0x1f0
[   84.461519]  [] ? __alloc_skb+0x8c/0x1f0
[   84.461523]  [] ? skb_dequeue+0x5d/0x80
[   84.461527]  [] usb_submit_urb+0x42e/0x5f0
[   84.461531]  [] ? __alloc_rx_skb+0x39/0x100
[   84.461536]  [] mwifiex_usb_submit_rx_urb+0xb2/0x170 
[mwifiex_usb]
[   84.461542]  [] mwifiex_usb_submit_rem_rx_urbs+0x45/0x50 
[mwifiex_usb]
[   84.461550]  [] mwifiex_rx_work_queue+0x10e/0x140 [mwifiex]
[   84.461556]  [] process_one_work+0x229/0x890
[   84.461559]  [] ? process_one_work+0x18c/0x890
[   84.461565]  [] worker_thread+0x53/0x470
[   84.461569]  [] ? process_one_work+0x890/0x890
[   84.461572]  [] kthread+0xf2/0x110
[   84.461577]  [] ? trace_hardirqs_on+0xd/0x10
[   84.461581]  [] ? kthread_create_on_node+0x230/0x230
[   84.461586]  [] ret_from_fork+0x42/0x70
[   84.461590]  [] ? kthread_create_on_node+0x230/0x230
[   84.461593] ---[ end trace 65103af5e6fb3444 ]---

Signed-off-by: Reyad Attiyat 
---
 drivers/net/wireless/mwifiex/usb.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/usb.c 
b/drivers/net/wireless/mwifiex/usb.c
index fd8027f..cd3ba76 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -235,9 +235,11 @@ setup_for_next:
if (card->rx_cmd_ep == context->ep) {
mwifiex_usb_submit_rx_urb(context, size);
} else {
-   context->skb = NULL;
-   if (atomic_read(>rx_pending) <= HIGH_RX_PENDING)
+   if (atomic_read(>rx_pending) <= HIGH_RX_PENDING){
mwifiex_usb_submit_rx_urb(context, size);
+   }else{
+ 

[PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
This commmit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint's
max packet length.

Signed-off-by: Reyad Attiyat 
---
 drivers/usb/host/xhci-ring.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..3d57a7a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_sgs;
int trb_buff_len, this_sg_len, running_total;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(>ep->desc));
 
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+&& !(urb->transfer_buffer_length % usb_endpoint_maxp(>ep->desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, "Creating zero length td.\n");
+   }
+
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
num_trbs, urb, 0, mem_flags);
@@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb->transfer_buffer_length;
 
first_trb = true;
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs > 1) {
+   if (num_trbs > last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed && num_trbs == 1) {
+   trb_buff_len = 0;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3176,7 +3188,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
if (running_total + trb_buff_len > urb->transfer_buffer_length)
trb_buff_len =
urb->transfer_buffer_length - running_total;
-   } while (running_total < urb->transfer_buffer_length);
+   } while (num_trbs > 0);
 
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+&& !(urb->transfer_buffer_length % usb_endpoint_maxp(>ep->desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, "Creating zero length td.\n");
+   }
 
ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
@@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb->transfer_buffer_length;
 
first_trb = true;
-
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 remainder = 0;
@@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
   

Re: [PATCH] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
Sorry I have forgotten to change the dp loop check line in the bulk_sg
function. Will resubmit.

On Sun, Jun 28, 2015 at 7:36 PM, Reyad Attiyat  wrote:
> This commit checks for the URB_ZERO_PACKET flag and creates an extra
> zero-length td if the urb transfer length is a multiple of the endpoint
> max packet length.
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/usb/host/xhci-ring.c | 41 -
>  1 file changed, 32 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 7d34cbf..fb24099 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> int num_sgs;
> int trb_buff_len, this_sg_len, running_total;
> unsigned int total_packet_count;
> +   bool zero_length_needed;
> bool first_trb;
> +   int last_trb;
> u64 addr;
> bool more_trbs_coming;
>
> @@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
> usb_endpoint_maxp(>ep->desc));
>
> +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
> +   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
> +&& !(urb->transfer_buffer_length % 
> usb_endpoint_maxp(>ep->desc));
> +   if(zero_length_needed){
> +   num_trbs++;
> +   xhci_dbg(xhci, "Creating zero length td.\n");
> +   }
> +
> trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
> ep_index, urb->stream_id,
> num_trbs, urb, 0, mem_flags);
> @@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> trb_buff_len = urb->transfer_buffer_length;
>
> first_trb = true;
> +   last_trb = zero_length_needed ? 2 : 1;
> /* Queue the first TRB, even if it's zero-length */
> do {
> u32 field = 0;
> @@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
> gfp_t mem_flags,
> /* Chain all the TRBs together; clear the chain bit in the 
> last
>  * TRB to indicate it's the last TRB in the chain.
>  */
> -   if (num_trbs > 1) {
> +   if (num_trbs > last_trb) {
> field |= TRB_CHAIN;
> -   } else {
> -   /* FIXME - add check for ZERO_PACKET flag before this 
> */
> +   } else if (num_trbs == last_trb) {
> td->last_trb = ep_ring->enqueue;
> field |= TRB_IOC;
> +   } else if (zero_length_needed && num_trbs == 1) {
> +   trb_buff_len = 0;
> }
>
> /* Only set interrupt on short packet for IN endpoints */
> @@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
> mem_flags,
> int num_trbs;
> struct xhci_generic_trb *start_trb;
> bool first_trb;
> +   int last_trb;
> bool more_trbs_coming;
> +   bool zero_length_needed;
> int start_cycle;
> u32 field, length_field;
>
> @@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
> mem_flags,
> num_trbs++;
> running_total += TRB_MAX_BUFF_SIZE;
> }
> -   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
> +
> +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
> +   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
> +&& !(urb->transfer_buffer_length % 
> usb_endpoint_maxp(>ep->desc));
> +   if(zero_length_needed){
> +   num_trbs++;
> +   xhci_dbg(xhci, "Creating zero length td.\n");
> +   }
>
> ret = prepare_transfer(xhci, xhci->devs[slot_id],
> ep_index, urb->stream_id,
> @@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
> mem_flags,
> trb_buff_len = urb->transfer_buffer_length;
>
> first_trb = true;
> -
> +   last_trb = zero_length_needed ? 2 : 1;
> /* Queue the first TRB, even if it's zero-length */
> do {
> u32 remainder = 0;
> @@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
> mem_flags

[PATCH] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
This commit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint 
max packet length.

Signed-off-by: Reyad Attiyat 
---
 drivers/usb/host/xhci-ring.c | 41 -
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..fb24099 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_sgs;
int trb_buff_len, this_sg_len, running_total;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(>ep->desc));
 
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+&& !(urb->transfer_buffer_length % usb_endpoint_maxp(>ep->desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, "Creating zero length td.\n");
+   }
+
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
num_trbs, urb, 0, mem_flags);
@@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb->transfer_buffer_length;
 
first_trb = true;
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs > 1) {
+   if (num_trbs > last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed && num_trbs == 1) {
+   trb_buff_len = 0;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+&& !(urb->transfer_buffer_length % usb_endpoint_maxp(>ep->desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, "Creating zero length td.\n");
+   }
 
ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
@@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb->transfer_buffer_length;
 
first_trb = true;
-
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 remainder = 0;
@@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs > 1) {
+
+   if (num_trbs > last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed && num_trbs == 1) {
+   trb_buff_len = 0;
}
 
 

[PATCH v2] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-28 Thread Reyad Attiyat
The newer firmware on MS Surface 2 tablets causes the type and touch cover 
keyboards to timeout when waiting for reports.
The quirk HID_QUIRK_NO_INIT_REPORTS allows them to function normally.

Signed-off-by: Reyad Attiyat 
---
 drivers/hid/usbhid/hid-quirks.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4696895e..b0e0a8c 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -87,6 +87,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
HID_QUIRK_NO_INIT_REPORTS },
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-28 Thread Reyad Attiyat
This is missing a device ID I will need to resubmit

Sorry,
Reyad Attiyat

On Fri, Jun 26, 2015 at 1:00 AM, Reyad Attiyat  wrote:
> The newer frimware on MS Surface 2 tablets causes the type and touch cover 
> keyboards to timeout when waiting for reports.
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/hid/usbhid/hid-quirks.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
> index 4696895e..19c6f74 100644
> --- a/drivers/hid/usbhid/hid-quirks.c
> +++ b/drivers/hid/usbhid/hid-quirks.c
> @@ -87,6 +87,8 @@ static const struct hid_blacklist {
> { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
> HID_QUIRK_ALWAYS_POLL },
> { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
> HID_QUIRK_ALWAYS_POLL },
> { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
> +   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
> HID_QUIRK_NO_INIT_REPORTS },
> +   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
> HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
> HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
> HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
> HID_QUIRK_NO_INIT_REPORTS },
> --
> 2.4.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-28 Thread Reyad Attiyat
This is missing a device ID I will need to resubmit

Sorry,
Reyad Attiyat

On Fri, Jun 26, 2015 at 1:00 AM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 The newer frimware on MS Surface 2 tablets causes the type and touch cover 
 keyboards to timeout when waiting for reports.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/hid/usbhid/hid-quirks.c | 2 ++
  1 file changed, 2 insertions(+)

 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
 index 4696895e..19c6f74 100644
 --- a/drivers/hid/usbhid/hid-quirks.c
 +++ b/drivers/hid/usbhid/hid-quirks.c
 @@ -87,6 +87,8 @@ static const struct hid_blacklist {
 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
 HID_QUIRK_ALWAYS_POLL },
 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
 HID_QUIRK_ALWAYS_POLL },
 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
 +   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
 HID_QUIRK_NO_INIT_REPORTS },
 +   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
 HID_QUIRK_NO_INIT_REPORTS },
 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
 HID_QUIRK_NO_INIT_REPORTS },
 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
 HID_QUIRK_NO_INIT_REPORTS },
 { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
 HID_QUIRK_NO_INIT_REPORTS },
 --
 2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-28 Thread Reyad Attiyat
The newer firmware on MS Surface 2 tablets causes the type and touch cover 
keyboards to timeout when waiting for reports.
The quirk HID_QUIRK_NO_INIT_REPORTS allows them to function normally.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/hid/usbhid/hid-quirks.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4696895e..b0e0a8c 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -87,6 +87,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
HID_QUIRK_NO_INIT_REPORTS },
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
This commit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint 
max packet length.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 41 -
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..fb24099 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_sgs;
int trb_buff_len, this_sg_len, running_total;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
usb_endpoint_maxp(urb-ep-desc));
 
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
+ !(urb-transfer_buffer_length % usb_endpoint_maxp(urb-ep-desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, Creating zero length td.\n);
+   }
+
trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
num_trbs, urb, 0, mem_flags);
@@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb-transfer_buffer_length;
 
first_trb = true;
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs  1) {
+   if (num_trbs  last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td-last_trb = ep_ring-enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed  num_trbs == 1) {
+   trb_buff_len = 0;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
+ !(urb-transfer_buffer_length % usb_endpoint_maxp(urb-ep-desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, Creating zero length td.\n);
+   }
 
ret = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
@@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb-transfer_buffer_length;
 
first_trb = true;
-
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 remainder = 0;
@@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs  1) {
+
+   if (num_trbs  last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td-last_trb = ep_ring-enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed  num_trbs == 1) {
+   trb_buff_len = 0;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3315,7 +3338,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci

Re: [PATCH] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
Sorry I have forgotten to change the dp loop check line in the bulk_sg
function. Will resubmit.

On Sun, Jun 28, 2015 at 7:36 PM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 This commit checks for the URB_ZERO_PACKET flag and creates an extra
 zero-length td if the urb transfer length is a multiple of the endpoint
 max packet length.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/usb/host/xhci-ring.c | 41 -
  1 file changed, 32 insertions(+), 9 deletions(-)

 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index 7d34cbf..fb24099 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 int num_sgs;
 int trb_buff_len, this_sg_len, running_total;
 unsigned int total_packet_count;
 +   bool zero_length_needed;
 bool first_trb;
 +   int last_trb;
 u64 addr;
 bool more_trbs_coming;

 @@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
 usb_endpoint_maxp(urb-ep-desc));

 +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
 +   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
 + !(urb-transfer_buffer_length % 
 usb_endpoint_maxp(urb-ep-desc));
 +   if(zero_length_needed){
 +   num_trbs++;
 +   xhci_dbg(xhci, Creating zero length td.\n);
 +   }
 +
 trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
 ep_index, urb-stream_id,
 num_trbs, urb, 0, mem_flags);
 @@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 trb_buff_len = urb-transfer_buffer_length;

 first_trb = true;
 +   last_trb = zero_length_needed ? 2 : 1;
 /* Queue the first TRB, even if it's zero-length */
 do {
 u32 field = 0;
 @@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
 gfp_t mem_flags,
 /* Chain all the TRBs together; clear the chain bit in the 
 last
  * TRB to indicate it's the last TRB in the chain.
  */
 -   if (num_trbs  1) {
 +   if (num_trbs  last_trb) {
 field |= TRB_CHAIN;
 -   } else {
 -   /* FIXME - add check for ZERO_PACKET flag before this 
 */
 +   } else if (num_trbs == last_trb) {
 td-last_trb = ep_ring-enqueue;
 field |= TRB_IOC;
 +   } else if (zero_length_needed  num_trbs == 1) {
 +   trb_buff_len = 0;
 }

 /* Only set interrupt on short packet for IN endpoints */
 @@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
 mem_flags,
 int num_trbs;
 struct xhci_generic_trb *start_trb;
 bool first_trb;
 +   int last_trb;
 bool more_trbs_coming;
 +   bool zero_length_needed;
 int start_cycle;
 u32 field, length_field;

 @@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
 mem_flags,
 num_trbs++;
 running_total += TRB_MAX_BUFF_SIZE;
 }
 -   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
 +
 +   /* Deal with URB_ZERO_PACKET - need one more td/trb */
 +   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
 + !(urb-transfer_buffer_length % 
 usb_endpoint_maxp(urb-ep-desc));
 +   if(zero_length_needed){
 +   num_trbs++;
 +   xhci_dbg(xhci, Creating zero length td.\n);
 +   }

 ret = prepare_transfer(xhci, xhci-devs[slot_id],
 ep_index, urb-stream_id,
 @@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
 mem_flags,
 trb_buff_len = urb-transfer_buffer_length;

 first_trb = true;
 -
 +   last_trb = zero_length_needed ? 2 : 1;
 /* Queue the first TRB, even if it's zero-length */
 do {
 u32 remainder = 0;
 @@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
 mem_flags,
 /* Chain all the TRBs together; clear the chain bit in the 
 last
  * TRB to indicate it's the last TRB in the chain.
  */
 -   if (num_trbs  1) {
 +
 +   if (num_trbs  last_trb) {
 field |= TRB_CHAIN;
 -   } else {
 -   /* FIXME - add check for ZERO_PACKET flag before this 
 */
 +   } else if (num_trbs == last_trb) {
 td-last_trb = ep_ring-enqueue

[PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

2015-06-28 Thread Reyad Attiyat
This commmit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint's
max packet length.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..3d57a7a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_sgs;
int trb_buff_len, this_sg_len, running_total;
unsigned int total_packet_count;
+   bool zero_length_needed;
bool first_trb;
+   int last_trb;
u64 addr;
bool more_trbs_coming;
 
@@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
total_packet_count = DIV_ROUND_UP(urb-transfer_buffer_length,
usb_endpoint_maxp(urb-ep-desc));
 
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
+ !(urb-transfer_buffer_length % usb_endpoint_maxp(urb-ep-desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, Creating zero length td.\n);
+   }
+
trb_buff_len = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
num_trbs, urb, 0, mem_flags);
@@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb-transfer_buffer_length;
 
first_trb = true;
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs  1) {
+   if (num_trbs  last_trb) {
field |= TRB_CHAIN;
-   } else {
-   /* FIXME - add check for ZERO_PACKET flag before this */
+   } else if (num_trbs == last_trb) {
td-last_trb = ep_ring-enqueue;
field |= TRB_IOC;
+   } else if (zero_length_needed  num_trbs == 1) {
+   trb_buff_len = 0;
}
 
/* Only set interrupt on short packet for IN endpoints */
@@ -3176,7 +3188,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
if (running_total + trb_buff_len  urb-transfer_buffer_length)
trb_buff_len =
urb-transfer_buffer_length - running_total;
-   } while (running_total  urb-transfer_buffer_length);
+   } while (num_trbs  0);
 
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb-stream_id,
@@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+   int last_trb;
bool more_trbs_coming;
+   bool zero_length_needed;
int start_cycle;
u32 field, length_field;
 
@@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
-   /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
+
+   /* Deal with URB_ZERO_PACKET - need one more td/trb */
+   zero_length_needed = (urb-transfer_flags  URB_ZERO_PACKET)
+ !(urb-transfer_buffer_length % usb_endpoint_maxp(urb-ep-desc));
+   if(zero_length_needed){
+   num_trbs++;
+   xhci_dbg(xhci, Creating zero length td.\n);
+   }
 
ret = prepare_transfer(xhci, xhci-devs[slot_id],
ep_index, urb-stream_id,
@@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
trb_buff_len = urb-transfer_buffer_length;
 
first_trb = true;
-
+   last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 remainder = 0;
@@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
 * TRB to indicate it's the last TRB in the chain.
 */
-   if (num_trbs  1) {
+
+   if (num_trbs  last_trb) {
field |= TRB_CHAIN

[PATCH] mwifiex: usb: Fix double add error when submitting rx urb

2015-06-28 Thread Reyad Attiyat
There is an error that can occur where the driver adds the same URB to USB 
submission list twice.
This happens since mwifiex_usb_submit_rem_rx can submit packets at same time as 
an rx urb complete callback.
This causes list corruption and is fixed by not setting the skb to NULL when 
submitting an rx packet.

[   84.461242] WARNING: CPU: 1 PID: 748 at lib/list_debug.c:36 
__list_add+0xcb/0xd0()
[   84.461245] list_add double add: new=8800c92b0c50, 
prev=8800c92b0c50, next=8800ced6c430.
[   84.461247] Modules linked in: rfcomm fuse cmac nf_conntrack_netbios_ns 
nf_conntrack_broadcast ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack 
ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat 
nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security 
ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 
nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bnep iptable_mangle 
iptable_security iptable_raw btusb btintel bluetooth mwifiex_usb mwifiex 
x86_pkg_temp_thermal cfg80211 coretemp r8712u(C) kvm_intel kvm hid_sensor_als 
hid_sensor_incl_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_accel_3d 
hid_sensor_gyro_3d hid_sensor_trigger hid_sensor_iio_common 
industrialio_triggered_buffer kfifo_buf rfkill iTCO_wdt industrialio 
iTCO_vendor_support
[   84.461316]  crc32_pclmul crc32c_intel ghash_clmulni_intel microcode 
snd_hda_codec_realtek vfat snd_hda_codec_generic fat snd_hda_codec_hdmi 
snd_hda_intel snd_hda_controller uvcvideo snd_hda_codec videobuf2_vmalloc 
videobuf2_memops snd_hwdep videobuf2_core snd_hda_core joydev v4l2_common 
videodev hid_sensor_hub snd_seq hid_multitouch media snd_seq_device snd_pcm 
snd_timer mei_me snd i2c_i801 lpc_ich mei soundcore tpm_infineon tpm_tis tpm 
i2c_hid i2c_designware_platform i2c_designware_core nfsd auth_rpcgss nfs_acl 
lockd grace sunrpc sch_fq_codel i915 i2c_algo_bit drm_kms_helper drm xhci_pci 
xhci_hcd ehci_pci sd_mod ehci_hcd video
[   84.461383] CPU: 1 PID: 748 Comm: kworker/u9:0 Tainted: G C  
4.1.0-rc5+ #163
[   84.461386] Hardware name: Microsoft Corporation Surface Pro 2/Surface Pro 
2, BIOS 2.05.0250 04/10/2015
[   84.461396] Workqueue: MWIFIEX_RX_WORK_QUEUE mwifiex_rx_work_queue [mwifiex]
[   84.461399]  81a8150e 8801174cf8e8 817df830 

[   84.461405]  8801174cf938 8801174cf928 810a54ba 
8800c86bd750
[   84.461410]  8800c92b0c50 8800c92b0c50 8800ced6c430 
88010c057178
[   84.461416] Call Trace:
[   84.461421]  [817df830] dump_stack+0x4f/0x7b
[   84.461428]  [810a54ba] warn_slowpath_common+0x8a/0xc0
[   84.461432]  [810a5536] warn_slowpath_fmt+0x46/0x50
[   84.461436]  [814109fb] __list_add+0xcb/0xd0
[   84.461442]  [815c551a] ? usb_hcd_link_urb_to_ep+0x2a/0xa0
[   84.461446]  [815c5570] usb_hcd_link_urb_to_ep+0x80/0xa0
[   84.461459]  [a004318a] prepare_transfer+0xaa/0x130 [xhci_hcd]
[   84.461470]  [a0044cf7] xhci_queue_bulk_tx+0xb7/0x7a0 [xhci_hcd]
[   84.461480]  [a003b67f] ? xhci_urb_enqueue+0x50f/0x660 [xhci_hcd]
[   84.461489]  [a003b67f] ? xhci_urb_enqueue+0x50f/0x660 [xhci_hcd]
[   84.461498]  [a003b735] xhci_urb_enqueue+0x5c5/0x660 [xhci_hcd]
[   84.461503]  [815c7ad3] usb_hcd_submit_urb+0x93/0xa70
[   84.461507]  [8168dde8] ? __alloc_skb+0x78/0x1f0
[   84.461511]  [8168d301] ? __kmalloc_reserve.isra.26+0x31/0x90
[   84.461515]  [8168ddbc] ? __alloc_skb+0x4c/0x1f0
[   84.461519]  [8168ddfc] ? __alloc_skb+0x8c/0x1f0
[   84.461523]  [8168badd] ? skb_dequeue+0x5d/0x80
[   84.461527]  [815c987e] usb_submit_urb+0x42e/0x5f0
[   84.461531]  [816931d9] ? __alloc_rx_skb+0x39/0x100
[   84.461536]  [a05aa372] mwifiex_usb_submit_rx_urb+0xb2/0x170 
[mwifiex_usb]
[   84.461542]  [a05aa5f5] mwifiex_usb_submit_rem_rx_urbs+0x45/0x50 
[mwifiex_usb]
[   84.461550]  [a07094be] mwifiex_rx_work_queue+0x10e/0x140 [mwifiex]
[   84.461556]  [810c4429] process_one_work+0x229/0x890
[   84.461559]  [810c438c] ? process_one_work+0x18c/0x890
[   84.461565]  [810c4ae3] worker_thread+0x53/0x470
[   84.461569]  [810c4a90] ? process_one_work+0x890/0x890
[   84.461572]  [810cb162] kthread+0xf2/0x110
[   84.461577]  [811031ad] ? trace_hardirqs_on+0xd/0x10
[   84.461581]  [810cb070] ? kthread_create_on_node+0x230/0x230
[   84.461586]  [817e9662] ret_from_fork+0x42/0x70
[   84.461590]  [810cb070] ? kthread_create_on_node+0x230/0x230
[   84.461593] ---[ end trace 65103af5e6fb3444 ]---

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/net/wireless/mwifiex/usb.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/usb.c 
b/drivers/net/wireless/mwifiex/usb.c
index fd8027f..cd3ba76 100644
--- a/drivers/net/wireless

[PATCH] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-26 Thread Reyad Attiyat
The newer frimware on MS Surface 2 tablets causes the type and touch cover 
keyboards to timeout when waiting for reports.

Signed-off-by: Reyad Attiyat 
---
 drivers/hid/usbhid/hid-quirks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4696895e..19c6f74 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -87,6 +87,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
HID_QUIRK_NO_INIT_REPORTS },
-- 
2.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] HID: microsoft: Add quirk for MS Surface Type/Touch cover

2015-06-26 Thread Reyad Attiyat
The newer frimware on MS Surface 2 tablets causes the type and touch cover 
keyboards to timeout when waiting for reports.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/hid/usbhid/hid-quirks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4696895e..19c6f74 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -87,6 +87,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, 
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
+   { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, 
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, 
HID_QUIRK_NO_INIT_REPORTS },
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Fix build warning, sizeof() called on dynamically
sized pointer, by removing the call and the dependent
function parameter. It is not needed or used in this
driver, when pushing values to an iio buffer.

Changes from v1
- Fix mistake in varible name

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 3ec777a..1e717c7 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, data);
@@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state->iio_vals,
-   sizeof(magn_state->iio_vals));
+   hid_sensor_push_data(indio_dev, magn_state->iio_vals);
 
return 0;
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Whoops looks like I typed an extra character, sorry should have caught this.
Thanks Sirinivas will resend.

On Fri, Jul 25, 2014 at 2:52 PM, Srinivas Pandruvada
 wrote:
> On 07/25/2014 12:32 PM, Reyad Attiyat wrote:
>>
>> Fix build warning, sizeof() called on dynamically
>> sized pointer, by removing the call and the dependent
>> function parameter. It is not needed or used in this
>> driver, when pushing values to an iio buffer.
>>
>> Signed-off-by: Reyad Attiyat 
>> ---
>>   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
>>   1 file changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> index 3ec777a..915ffb9 100644
>> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> @@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
>>   };
>>
>>   /* Function to push data to buffer */
>> -static void hid_sensor_push_data(struct iio_dev *indio_dev, const void
>> *data,
>> -   int len)
>> +static void hid_sensor_push_data(struct iio_dev *indio_dev, const void
>> *data)
>>   {
>> dev_dbg(_dev->dev, "hid_sensor_push_data\n");
>> iio_push_to_buffers(indio_dev, data);
>> @@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct
>> hid_sensor_hub_device *hsdev,
>>
>> dev_dbg(_dev->dev, "magn_3d_proc_event\n");
>> if (atomic_read(_state->common_attributes.data_ready))
>> -   hid_sensor_push_data(indio_dev,
>> -   magn_state->iio_vals,
>> -   sizeof(magn_state->iio_vals));
>> +   hid_sensor_push_data(indio_devm, magn_state->iio_vals);
>
> Is it indio_devm,  not indio_dev?
>
> Thanks,
> Srinivas
>>
>>
>> return 0;
>>   }
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Fix build warning, sizeof() called on dynamically
sized pointer, by removing the call and the dependent
function parameter. It is not needed or used in this
driver, when pushing values to an iio buffer.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 3ec777a..915ffb9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, data);
@@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state->iio_vals,
-   sizeof(magn_state->iio_vals));
+   hid_sensor_push_data(indio_devm, magn_state->iio_vals);
 
return 0;
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] hid: usbhid: Use flag HID_DISCONNECTED when a usb device is removed

2014-07-25 Thread Reyad Attiyat
The kernel panic happened when the iio sensor hid usb device was
removed. It tries to set the power state by calling hid_hw_request().
This was on kernel 3.16-rc6
https://gist.github.com/soda0289/2ff543d9cfff6f92c360#file-kernel-panic-when-iio-sensor-usb-device-is-removed

On Fri, Jul 25, 2014 at 12:13 AM, Reyad Attiyat  wrote:
> Set disconnected flag in struct usbhid when a usb device
> is removed. Check for disconnected flag before sending urb
> requests. This prevents a kernel panic when a hid driver calls
> hid_hw_request() after removing a usb device.
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/hid/usbhid/hid-core.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index 7b88f4c..c8fa957 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device 
> *hid, struct hid_report *re
> int head;
> struct usbhid_device *usbhid = hid->driver_data;
>
> -   if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
> +   if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
> +   test_bit(HID_DISCONNECTED, >iofl))
> return;
>
> if (usbhid->urbout && dir == USB_DIR_OUT && report->type == 
> HID_OUTPUT_REPORT) {
> @@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface 
> *intf)
> return;
>
> usbhid = hid->driver_data;
> +   spin_lock_irq(>lock);   /* Sync with error and led handlers */
> +   set_bit(HID_DISCONNECTED, >iofl);
> +   spin_unlock_irq(>lock);
> hid_destroy_device(hid);
> kfree(usbhid);
>  }
> --
> 1.9.3
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] hid: usbhid: Use flag HID_DISCONNECTED when a usb device is removed

2014-07-25 Thread Reyad Attiyat
The kernel panic happened when the iio sensor hid usb device was
removed. It tries to set the power state by calling hid_hw_request().
This was on kernel 3.16-rc6
https://gist.github.com/soda0289/2ff543d9cfff6f92c360#file-kernel-panic-when-iio-sensor-usb-device-is-removed

On Fri, Jul 25, 2014 at 12:13 AM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 Set disconnected flag in struct usbhid when a usb device
 is removed. Check for disconnected flag before sending urb
 requests. This prevents a kernel panic when a hid driver calls
 hid_hw_request() after removing a usb device.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/hid/usbhid/hid-core.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

 diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
 index 7b88f4c..c8fa957 100644
 --- a/drivers/hid/usbhid/hid-core.c
 +++ b/drivers/hid/usbhid/hid-core.c
 @@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device 
 *hid, struct hid_report *re
 int head;
 struct usbhid_device *usbhid = hid-driver_data;

 -   if ((hid-quirks  HID_QUIRK_NOGET)  dir == USB_DIR_IN)
 +   if (((hid-quirks  HID_QUIRK_NOGET)  dir == USB_DIR_IN) ||
 +   test_bit(HID_DISCONNECTED, usbhid-iofl))
 return;

 if (usbhid-urbout  dir == USB_DIR_OUT  report-type == 
 HID_OUTPUT_REPORT) {
 @@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface 
 *intf)
 return;

 usbhid = hid-driver_data;
 +   spin_lock_irq(usbhid-lock);   /* Sync with error and led handlers */
 +   set_bit(HID_DISCONNECTED, usbhid-iofl);
 +   spin_unlock_irq(usbhid-lock);
 hid_destroy_device(hid);
 kfree(usbhid);
  }
 --
 1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Fix build warning, sizeof() called on dynamically
sized pointer, by removing the call and the dependent
function parameter. It is not needed or used in this
driver, when pushing values to an iio buffer.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 3ec777a..915ffb9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(indio_dev-dev, hid_sensor_push_data\n);
iio_push_to_buffers(indio_dev, data);
@@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state-iio_vals,
-   sizeof(magn_state-iio_vals));
+   hid_sensor_push_data(indio_devm, magn_state-iio_vals);
 
return 0;
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Whoops looks like I typed an extra character, sorry should have caught this.
Thanks Sirinivas will resend.

On Fri, Jul 25, 2014 at 2:52 PM, Srinivas Pandruvada
srinivas.pandruv...@linux.intel.com wrote:
 On 07/25/2014 12:32 PM, Reyad Attiyat wrote:

 Fix build warning, sizeof() called on dynamically
 sized pointer, by removing the call and the dependent
 function parameter. It is not needed or used in this
 driver, when pushing values to an iio buffer.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
   1 file changed, 2 insertions(+), 5 deletions(-)

 diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 index 3ec777a..915ffb9 100644
 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 @@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
   };

   /* Function to push data to buffer */
 -static void hid_sensor_push_data(struct iio_dev *indio_dev, const void
 *data,
 -   int len)
 +static void hid_sensor_push_data(struct iio_dev *indio_dev, const void
 *data)
   {
 dev_dbg(indio_dev-dev, hid_sensor_push_data\n);
 iio_push_to_buffers(indio_dev, data);
 @@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct
 hid_sensor_hub_device *hsdev,

 dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
 if (atomic_read(magn_state-common_attributes.data_ready))
 -   hid_sensor_push_data(indio_dev,
 -   magn_state-iio_vals,
 -   sizeof(magn_state-iio_vals));
 +   hid_sensor_push_data(indio_devm, magn_state-iio_vals);

 Is it indio_devm,  not indio_dev?

 Thanks,
 Srinivas


 return 0;
   }


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] iio: hid-sensor-magn-3d: Fix build warning

2014-07-25 Thread Reyad Attiyat
Fix build warning, sizeof() called on dynamically
sized pointer, by removing the call and the dependent
function parameter. It is not needed or used in this
driver, when pushing values to an iio buffer.

Changes from v1
- Fix mistake in varible name

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 3ec777a..1e717c7 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(indio_dev-dev, hid_sensor_push_data\n);
iio_push_to_buffers(indio_dev, data);
@@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state-iio_vals,
-   sizeof(magn_state-iio_vals));
+   hid_sensor_push_data(indio_dev, magn_state-iio_vals);
 
return 0;
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] hid: usbhid: Use flag HID_DISCONNECTED when a usb device is removed

2014-07-24 Thread Reyad Attiyat
Set disconnected flag in struct usbhid when a usb device
is removed. Check for disconnected flag before sending urb
requests. This prevents a kernel panic when a hid driver calls
hid_hw_request() after removing a usb device.

Signed-off-by: Reyad Attiyat 
---
 drivers/hid/usbhid/hid-core.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7b88f4c..c8fa957 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device *hid, 
struct hid_report *re
int head;
struct usbhid_device *usbhid = hid->driver_data;
 
-   if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
+   if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
+   test_bit(HID_DISCONNECTED, >iofl))
return;
 
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == 
HID_OUTPUT_REPORT) {
@@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface *intf)
return;
 
usbhid = hid->driver_data;
+   spin_lock_irq(>lock);   /* Sync with error and led handlers */
+   set_bit(HID_DISCONNECTED, >iofl);
+   spin_unlock_irq(>lock);
hid_destroy_device(hid);
kfree(usbhid);
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] hid: usbhid: Use flag HID_DISCONNECTED when a usb device is removed

2014-07-24 Thread Reyad Attiyat
Set disconnected flag in struct usbhid when a usb device
is removed. Check for disconnected flag before sending urb
requests. This prevents a kernel panic when a hid driver calls
hid_hw_request() after removing a usb device.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/hid/usbhid/hid-core.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7b88f4c..c8fa957 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device *hid, 
struct hid_report *re
int head;
struct usbhid_device *usbhid = hid-driver_data;
 
-   if ((hid-quirks  HID_QUIRK_NOGET)  dir == USB_DIR_IN)
+   if (((hid-quirks  HID_QUIRK_NOGET)  dir == USB_DIR_IN) ||
+   test_bit(HID_DISCONNECTED, usbhid-iofl))
return;
 
if (usbhid-urbout  dir == USB_DIR_OUT  report-type == 
HID_OUTPUT_REPORT) {
@@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface *intf)
return;
 
usbhid = hid-driver_data;
+   spin_lock_irq(usbhid-lock);   /* Sync with error and led handlers */
+   set_bit(HID_DISCONNECTED, usbhid-iofl);
+   spin_unlock_irq(usbhid-lock);
hid_destroy_device(hid);
kfree(usbhid);
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-20 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat 
Acked-by: Srinivas Pandruvada 
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events

[PATCH v7 0/4] iio: Add support for rotation from north

2014-07-20 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V6
Remove sizeof from function hid_sensor_push_data as it is not used or 
passed to iio_push_to_buffer

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-20 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat 
Acked-by: Srinivas Pandruvada 
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+   [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+   [IIO_MOD_NORTH_TRUE] = "from_north_true",
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-20 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat 
Acked-by: Srinivas Pandruvada 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 161fbd4..1e717c7 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -242,6 +286,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-20 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v6
- Fix kernel build error for invalid sizeof by removing the parameter
from the hid_sensor_push_data

Signed-off-by: Reyad Attiyat 
Acked-by: Srinivas Pandruvada 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 152 ++
 1 file changed, 105 insertions(+), 47 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index b2b0937..161fbd4 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -126,8 +128,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state->magn[chan->scan_index].report_id;
-   address = magn_3d_addresses[chan->scan_index];
+   magn_state->magn[chan->address].report_id;
+   address = magn_3d_addresses[chan->address];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state->common_attributes.hsdev,
@@ -200,8 +202,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, data);
@@ -217,9 +218,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state->magn_val,
-   sizeof(magn_state->magn_val));
+   hid_sensor_push_data(indio_dev, magn_state->iio_vals);
 
return 0;
 }
@@ -233,52 +232,119 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   iio_val = magn_state->magn_val_addr[offset];
+
+   if (iio_val != NULL)
+   *iio_val = *((u32 *)raw_data);
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usag

[PATCH v7 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-20 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v6
- Fix kernel build error for invalid sizeof by removing the parameter
from the hid_sensor_push_data

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
Acked-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 152 ++
 1 file changed, 105 insertions(+), 47 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index b2b0937..161fbd4 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -126,8 +128,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state-magn[chan-scan_index].report_id;
-   address = magn_3d_addresses[chan-scan_index];
+   magn_state-magn[chan-address].report_id;
+   address = magn_3d_addresses[chan-address];
if (report_id = 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state-common_attributes.hsdev,
@@ -200,8 +202,7 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
-   int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
 {
dev_dbg(indio_dev-dev, hid_sensor_push_data\n);
iio_push_to_buffers(indio_dev, data);
@@ -217,9 +218,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
 
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
-   hid_sensor_push_data(indio_dev,
-   magn_state-magn_val,
-   sizeof(magn_state-magn_val));
+   hid_sensor_push_data(indio_dev, magn_state-iio_vals);
 
return 0;
 }
@@ -233,52 +232,119 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   iio_val = magn_state-magn_val_addr[offset];
+
+   if (iio_val != NULL)
+   *iio_val = *((u32 *)raw_data);
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int

[PATCH v7 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-20 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
Acked-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = quaternion,
[IIO_MOD_TEMP_AMBIENT] = ambient,
[IIO_MOD_TEMP_OBJECT] = object,
+   [IIO_MOD_NORTH_MAGN] = from_north_magnetic,
+   [IIO_MOD_NORTH_TRUE] = from_north_true,
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = from_north_magnetic_tilt_comp,
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = from_north_true_tilt_comp,
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-20 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
Acked-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 161fbd4..1e717c7 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -242,6 +286,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 0/4] iio: Add support for rotation from north

2014-07-20 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V6
Remove sizeof from function hid_sensor_push_data as it is not used or 
passed to iio_push_to_buffer

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-20 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
Acked-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value

[PATCH v6 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-17 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+   [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+   [IIO_MOD_NORTH_TRUE] = "from_north_true",
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 0/4] iio: Add support for rotation from north

2014-07-17 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V5
- Fix kernel panics from dereference

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-17 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v5
-Fixed kernel panic from invalid pointer dereference
-Fixed variable assignment style

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 149 ++
 1 file changed, 105 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index b2b0937..d3b9114 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -126,8 +128,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state->magn[chan->scan_index].report_id;
-   address = magn_3d_addresses[chan->scan_index];
+   magn_state->magn[chan->address].report_id;
+   address = magn_3d_addresses[chan->address];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state->common_attributes.hsdev,
@@ -218,8 +220,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state->magn_val,
-   sizeof(magn_state->magn_val));
+   magn_state->iio_vals,
+   sizeof(magn_state->iio_vals));
 
return 0;
 }
@@ -233,52 +235,119 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   iio_val = magn_state->magn_val_addr[offset];
+
+   if (iio_val != NULL)
+   *iio_val = *((u32 *)raw_data);
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   struct iio_chan_spec *channels,
+   struct iio_chan_spec **channels,
+   int *chan_count,
unsigned usage_id,
struct magn_3d

[PATCH v6 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-17 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat 
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value
@@ -588,6 +616,18

[PATCH v6 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-17 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index d3b9114..3ec777a 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -245,6 +289,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-17 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index d3b9114..3ec777a 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -245,6 +289,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-17 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value

[PATCH v6 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-17 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v5
-Fixed kernel panic from invalid pointer dereference
-Fixed variable assignment style

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 149 ++
 1 file changed, 105 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index b2b0937..d3b9114 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -126,8 +128,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state-magn[chan-scan_index].report_id;
-   address = magn_3d_addresses[chan-scan_index];
+   magn_state-magn[chan-address].report_id;
+   address = magn_3d_addresses[chan-address];
if (report_id = 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state-common_attributes.hsdev,
@@ -218,8 +220,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state-magn_val,
-   sizeof(magn_state-magn_val));
+   magn_state-iio_vals,
+   sizeof(magn_state-iio_vals));
 
return 0;
 }
@@ -233,52 +235,119 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   iio_val = magn_state-magn_val_addr[offset];
+
+   if (iio_val != NULL)
+   *iio_val = *((u32 *)raw_data);
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   struct iio_chan_spec *channels,
+   struct iio_chan_spec **channels,
+   int *chan_count,
unsigned usage_id,
struct magn_3d_state *st)
 {
-   int ret;
int i

[PATCH v6 0/4] iio: Add support for rotation from north

2014-07-17 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V5
- Fix kernel panics from dereference

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-17 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = quaternion,
[IIO_MOD_TEMP_AMBIENT] = ambient,
[IIO_MOD_TEMP_OBJECT] = object,
+   [IIO_MOD_NORTH_MAGN] = from_north_magnetic,
+   [IIO_MOD_NORTH_TRUE] = from_north_true,
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = from_north_magnetic_tilt_comp,
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = from_north_true_tilt_comp,
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 0/4] iio: Add support for rotation from north

2014-07-15 Thread Reyad Attiyat
Hey Srinivas

Thanks for looking into this for me!
I'll fix it up and resubmit soon.

On Tue, Jul 15, 2014 at 4:39 PM, Srinivas Pandruvada
 wrote:
> Hi,
>
> Since you have only one attribute, it is working for you.
> There is a dereference error in *channels.
>
> Check the attached diff, which will fix this.
>
> Thanks,
> Srinivas
>
>
> On 07/09/2014 03:12 PM, Reyad Attiyat wrote:
>>
>> Hey Srinivas,
>>
>> I did look into the panic you sent. I wasn't sure exactly what caused
>> the NULL pointer.
>> I tested it with out applying the last rotation from north patch, so
>> no hid usages are found, my device only has rotation_from_north, and
>> hid_parse_report() would return -EINVAL.
>> I added another check to make sure a iio channel were set up, and
>> return -EINVAL if not, but couldn't think of anything else.
>>
>> Could you test this version with dynamic debugging and see if it is
>> finding any hid usage attributes.
>> Any ideas what could cause this? I think I'm handling errors properly
>> by returning what parse_report returns (-EINVAL or -ENOMEM) in probe
>>
>> Thanks,
>> Reyad Attiyat
>>
>> On Wed, Jul 9, 2014 at 2:45 PM, Srinivas Pandruvada
>>  wrote:
>>>
>>> On 07/09/2014 12:30 PM, Reyad Attiyat wrote:
>>>>
>>>> This series of patches modifies magn-3d driver to handle the rotation
>>>> from north usage. This is done by scanning the report and then building
>>>> the iio arrays (vals and channels) dynamically.
>>>>
>>>> Changes from V4
>>>> I use the address field of struct iio_chan_spec to hold the array index
>>>> of the usage attribute. The scan_index field is generated when creating
>>>> an iio channel.
>>>>
>>>> Reyad Attiyat (4):
>>>> iio: Documentation: Add documentation for rotation from north sensor
>>>>   usage attributes
>>>> iio: types: Added support for rotation from north usage attributes
>>>> iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
>>>>   iio channels
>>>> iio: hid-sensor-magn-3d: Add support for rotation from north
>>>>
>>>>Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
>>>>drivers/iio/industrialio-core.c   |   4 +
>>>>drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199
>>>> --
>>>>include/linux/iio/types.h |   4 +
>>>>4 files changed, 245 insertions(+), 44 deletions(-)
>>>>
>>> Did you get chance to look at the cause of panic?
>>>
>>> Thanks,
>>> Srinivas
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 0/4] iio: Add support for rotation from north

2014-07-15 Thread Reyad Attiyat
Hey Srinivas

Thanks for looking into this for me!
I'll fix it up and resubmit soon.

On Tue, Jul 15, 2014 at 4:39 PM, Srinivas Pandruvada
srinivas.pandruv...@linux.intel.com wrote:
 Hi,

 Since you have only one attribute, it is working for you.
 There is a dereference error in *channels.

 Check the attached diff, which will fix this.

 Thanks,
 Srinivas


 On 07/09/2014 03:12 PM, Reyad Attiyat wrote:

 Hey Srinivas,

 I did look into the panic you sent. I wasn't sure exactly what caused
 the NULL pointer.
 I tested it with out applying the last rotation from north patch, so
 no hid usages are found, my device only has rotation_from_north, and
 hid_parse_report() would return -EINVAL.
 I added another check to make sure a iio channel were set up, and
 return -EINVAL if not, but couldn't think of anything else.

 Could you test this version with dynamic debugging and see if it is
 finding any hid usage attributes.
 Any ideas what could cause this? I think I'm handling errors properly
 by returning what parse_report returns (-EINVAL or -ENOMEM) in probe

 Thanks,
 Reyad Attiyat

 On Wed, Jul 9, 2014 at 2:45 PM, Srinivas Pandruvada
 srinivas.pandruv...@linux.intel.com wrote:

 On 07/09/2014 12:30 PM, Reyad Attiyat wrote:

 This series of patches modifies magn-3d driver to handle the rotation
 from north usage. This is done by scanning the report and then building
 the iio arrays (vals and channels) dynamically.

 Changes from V4
 I use the address field of struct iio_chan_spec to hold the array index
 of the usage attribute. The scan_index field is generated when creating
 an iio channel.

 Reyad Attiyat (4):
 iio: Documentation: Add documentation for rotation from north sensor
   usage attributes
 iio: types: Added support for rotation from north usage attributes
 iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
   iio channels
 iio: hid-sensor-magn-3d: Add support for rotation from north

Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
drivers/iio/industrialio-core.c   |   4 +
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199
 --
include/linux/iio/types.h |   4 +
4 files changed, 245 insertions(+), 44 deletions(-)

 Did you get chance to look at the cause of panic?

 Thanks,
 Srinivas


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 0/4] iio: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
Hey Srinivas,

I did look into the panic you sent. I wasn't sure exactly what caused
the NULL pointer.
I tested it with out applying the last rotation from north patch, so
no hid usages are found, my device only has rotation_from_north, and
hid_parse_report() would return -EINVAL.
I added another check to make sure a iio channel were set up, and
return -EINVAL if not, but couldn't think of anything else.

Could you test this version with dynamic debugging and see if it is
finding any hid usage attributes.
Any ideas what could cause this? I think I'm handling errors properly
by returning what parse_report returns (-EINVAL or -ENOMEM) in probe

Thanks,
Reyad Attiyat

On Wed, Jul 9, 2014 at 2:45 PM, Srinivas Pandruvada
 wrote:
> On 07/09/2014 12:30 PM, Reyad Attiyat wrote:
>>
>> This series of patches modifies magn-3d driver to handle the rotation
>> from north usage. This is done by scanning the report and then building
>> the iio arrays (vals and channels) dynamically.
>>
>> Changes from V4
>> I use the address field of struct iio_chan_spec to hold the array index
>> of the usage attribute. The scan_index field is generated when creating
>> an iio channel.
>>
>> Reyad Attiyat (4):
>>iio: Documentation: Add documentation for rotation from north sensor
>>  usage attributes
>>iio: types: Added support for rotation from north usage attributes
>>iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
>>  iio channels
>>iio: hid-sensor-magn-3d: Add support for rotation from north
>>
>>   Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
>>   drivers/iio/industrialio-core.c   |   4 +
>>   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199
>> --
>>   include/linux/iio/types.h |   4 +
>>   4 files changed, 245 insertions(+), 44 deletions(-)
>>
> Did you get chance to look at the cause of panic?
>
> Thanks,
> Srinivas
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-09 Thread Reyad Attiyat
Hey  Jonathan,

I noticed this patch fails checkpatch script. I made small change and
forgot to double check, sorry.
It complains of assigment in if statement in capture_value:
if (!!(iio_val = magn_state->magn_val_addr[offset]))


I'll break this into two lines if your ok with this implementation and
don't believe it needs any other changes

Thanks.

On Wed, Jul 9, 2014 at 2:30 PM, Reyad Attiyat  wrote:
> Scan for and count the HID usage attributes supported by the driver.
> This allows for the driver to only setup the IIO channels for the
> sensor usages present in the HID USB reports.
>
> Changes from v4
> Renamed iio_val array to iio_vals
> Renamed return value of hid sensor attribute for loop
> Fixed formatting
> Added comment about magn_val_addr and iio_vals
> Added more debugging information and checks
> Removed static initalizing of scan_index, it is now set dynamically
> Use struct iio_chan_spec address field to store magn array index (could be 
> set statically)
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/iio/magnetometer/hid-sensor-magn-3d.c | 144 
> ++
>  1 file changed, 100 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> index 41cf29e..f69664b 100644
> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> @@ -42,7 +42,12 @@ struct magn_3d_state {
> struct hid_sensor_hub_callbacks callbacks;
> struct hid_sensor_common common_attributes;
> struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
> -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
> +
> +   /* dynamically sized array to hold sensor values */
> +   u32 *iio_vals;
> +   /* array of pointers to sensor value */
> +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
> +
> int scale_pre_decml;
> int scale_post_decml;
> int scale_precision;
> @@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
> BIT(IIO_CHAN_INFO_SCALE) |
> BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> BIT(IIO_CHAN_INFO_HYSTERESIS),
> -   .scan_index = CHANNEL_SCAN_INDEX_X,
> }, {
> .type = IIO_MAGN,
> .modified = 1,
> @@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
> BIT(IIO_CHAN_INFO_SCALE) |
> BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> BIT(IIO_CHAN_INFO_HYSTERESIS),
> -   .scan_index = CHANNEL_SCAN_INDEX_Y,
> }, {
> .type = IIO_MAGN,
> .modified = 1,
> @@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
> BIT(IIO_CHAN_INFO_SCALE) |
> BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> BIT(IIO_CHAN_INFO_HYSTERESIS),
> -   .scan_index = CHANNEL_SCAN_INDEX_Z,
> }
>  };
>
> @@ -127,8 +129,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
> msleep_interruptible(poll_value * 2);
>
> report_id =
> -   magn_state->magn[chan->scan_index].report_id;
> -   address = magn_3d_addresses[chan->scan_index];
> +   magn_state->magn[chan->address].report_id;
> +   address = magn_3d_addresses[chan->address];
> if (report_id >= 0)
> *val = sensor_hub_input_attr_get_raw_value(
> magn_state->common_attributes.hsdev,
> @@ -221,8 +223,8 @@ static int magn_3d_proc_event(struct 
> hid_sensor_hub_device *hsdev,
> dev_dbg(_dev->dev, "magn_3d_proc_event\n");
> if (atomic_read(_state->common_attributes.data_ready))
> hid_sensor_push_data(indio_dev,
> -   magn_state->magn_val,
> -   sizeof(magn_state->magn_val));
> +   magn_state->iio_vals,
> +   sizeof(magn_state->iio_vals));
>
> return 0;
>  }
> @@ -236,52 +238,114 @@ static int magn_3d_capture_sample(struct 
> hid_sensor_hub_device *hsdev,
> struct iio_dev *indio_dev = platform_get_drvdata(priv);
> struct magn_3d_state *magn_state = iio_priv(indio_dev);
> int offset;
> -   int ret = -EINVAL;
> +   int ret = 0;
> +   u32 *iio_val = NULL;
>
> switch (usage_id) {
> case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
> case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
> case HID_USAGE_SENSOR

[PATCH v5 0/4] iio: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V4
I use the address field of struct iio_chan_spec to hold the array index
of the usage attribute. The scan_index field is generated when creating
an iio channel.

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-09 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat 
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value
@@ -588,6 +616,18

[PATCH v5 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-09 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v4
Renamed iio_val array to iio_vals
Renamed return value of hid sensor attribute for loop
Fixed formatting
Added comment about magn_val_addr and iio_vals
Added more debugging information and checks
Removed static initalizing of scan_index, it is now set dynamically
Use struct iio_chan_spec address field to store magn array index (could be set 
statically)

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 144 ++
 1 file changed, 100 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..f69664b 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -127,8 +129,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state->magn[chan->scan_index].report_id;
-   address = magn_3d_addresses[chan->scan_index];
+   magn_state->magn[chan->address].report_id;
+   address = magn_3d_addresses[chan->address];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state->common_attributes.hsdev,
@@ -221,8 +223,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state->magn_val,
-   sizeof(magn_state->magn_val));
+   magn_state->iio_vals,
+   sizeof(magn_state->iio_vals));
 
return 0;
 }
@@ -236,52 +238,114 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   if (!!(iio_val = magn_state->magn_val_addr[offset]))
+   *iio_val = *(u32 *)raw_data;
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   

[PATCH v5 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Changes from v4
Removed the scan index as this is set dynamically

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index f69664b..b9391c5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -248,6 +292,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-09 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+   [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+   [IIO_MOD_NORTH_TRUE] = "from_north_true",
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 2/4] iio: types: Added support for rotation from north usage attributes

2014-07-09 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = quaternion,
[IIO_MOD_TEMP_AMBIENT] = ambient,
[IIO_MOD_TEMP_OBJECT] = object,
+   [IIO_MOD_NORTH_MAGN] = from_north_magnetic,
+   [IIO_MOD_NORTH_TRUE] = from_north_true,
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = from_north_magnetic_tilt_comp,
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = from_north_true_tilt_comp,
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Changes from v4
Removed the scan index as this is set dynamically

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 53 ++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index f69664b..b9391c5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -57,7 +61,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -89,6 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
}
 };
 
@@ -248,6 +292,13 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ CHANNEL_SCAN_INDEX_X;
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+   + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-07-09 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..995642f 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value

[PATCH v5 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-09 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Changes from v4
Renamed iio_val array to iio_vals
Renamed return value of hid sensor attribute for loop
Fixed formatting
Added comment about magn_val_addr and iio_vals
Added more debugging information and checks
Removed static initalizing of scan_index, it is now set dynamically
Use struct iio_chan_spec address field to store magn array index (could be set 
statically)

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 144 ++
 1 file changed, 100 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..f69664b 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+   /* dynamically sized array to hold sensor values */
+   u32 *iio_vals;
+   /* array of pointers to sensor value */
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
}
 };
 
@@ -127,8 +129,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
 
report_id =
-   magn_state-magn[chan-scan_index].report_id;
-   address = magn_3d_addresses[chan-scan_index];
+   magn_state-magn[chan-address].report_id;
+   address = magn_3d_addresses[chan-address];
if (report_id = 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state-common_attributes.hsdev,
@@ -221,8 +223,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state-magn_val,
-   sizeof(magn_state-magn_val));
+   magn_state-iio_vals,
+   sizeof(magn_state-iio_vals));
 
return 0;
 }
@@ -236,52 +238,114 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
-   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+   + CHANNEL_SCAN_INDEX_X;
break;
default:
-   break;
+   return -EINVAL;
}
 
+   if (!!(iio_val = magn_state-magn_val_addr[offset]))
+   *iio_val = *(u32 *)raw_data;
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   struct iio_chan_spec *channels

[PATCH v5 0/4] iio: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
This series of patches modifies magn-3d driver to handle the rotation
from north usage. This is done by scanning the report and then building
the iio arrays (vals and channels) dynamically.

Changes from V4
I use the address field of struct iio_chan_spec to hold the array index
of the usage attribute. The scan_index field is generated when creating
an iio channel.

Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199 --
 include/linux/iio/types.h |   4 +
 4 files changed, 245 insertions(+), 44 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-09 Thread Reyad Attiyat
Hey  Jonathan,

I noticed this patch fails checkpatch script. I made small change and
forgot to double check, sorry.
It complains of assigment in if statement in capture_value:
if (!!(iio_val = magn_state-magn_val_addr[offset]))


I'll break this into two lines if your ok with this implementation and
don't believe it needs any other changes

Thanks.

On Wed, Jul 9, 2014 at 2:30 PM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 Scan for and count the HID usage attributes supported by the driver.
 This allows for the driver to only setup the IIO channels for the
 sensor usages present in the HID USB reports.

 Changes from v4
 Renamed iio_val array to iio_vals
 Renamed return value of hid sensor attribute for loop
 Fixed formatting
 Added comment about magn_val_addr and iio_vals
 Added more debugging information and checks
 Removed static initalizing of scan_index, it is now set dynamically
 Use struct iio_chan_spec address field to store magn array index (could be 
 set statically)

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/iio/magnetometer/hid-sensor-magn-3d.c | 144 
 ++
  1 file changed, 100 insertions(+), 44 deletions(-)

 diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
 b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 index 41cf29e..f69664b 100644
 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 @@ -42,7 +42,12 @@ struct magn_3d_state {
 struct hid_sensor_hub_callbacks callbacks;
 struct hid_sensor_common common_attributes;
 struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
 -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
 +
 +   /* dynamically sized array to hold sensor values */
 +   u32 *iio_vals;
 +   /* array of pointers to sensor value */
 +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
 +
 int scale_pre_decml;
 int scale_post_decml;
 int scale_precision;
 @@ -66,7 +71,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
 BIT(IIO_CHAN_INFO_SCALE) |
 BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_X,
 }, {
 .type = IIO_MAGN,
 .modified = 1,
 @@ -76,7 +80,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
 BIT(IIO_CHAN_INFO_SCALE) |
 BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_Y,
 }, {
 .type = IIO_MAGN,
 .modified = 1,
 @@ -86,7 +89,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
 BIT(IIO_CHAN_INFO_SCALE) |
 BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_Z,
 }
  };

 @@ -127,8 +129,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
 msleep_interruptible(poll_value * 2);

 report_id =
 -   magn_state-magn[chan-scan_index].report_id;
 -   address = magn_3d_addresses[chan-scan_index];
 +   magn_state-magn[chan-address].report_id;
 +   address = magn_3d_addresses[chan-address];
 if (report_id = 0)
 *val = sensor_hub_input_attr_get_raw_value(
 magn_state-common_attributes.hsdev,
 @@ -221,8 +223,8 @@ static int magn_3d_proc_event(struct 
 hid_sensor_hub_device *hsdev,
 dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
 if (atomic_read(magn_state-common_attributes.data_ready))
 hid_sensor_push_data(indio_dev,
 -   magn_state-magn_val,
 -   sizeof(magn_state-magn_val));
 +   magn_state-iio_vals,
 +   sizeof(magn_state-iio_vals));

 return 0;
  }
 @@ -236,52 +238,114 @@ static int magn_3d_capture_sample(struct 
 hid_sensor_hub_device *hsdev,
 struct iio_dev *indio_dev = platform_get_drvdata(priv);
 struct magn_3d_state *magn_state = iio_priv(indio_dev);
 int offset;
 -   int ret = -EINVAL;
 +   int ret = 0;
 +   u32 *iio_val = NULL;

 switch (usage_id) {
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
 -   offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
 -   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
 -   *(u32 *)raw_data;
 -   ret = 0;
 +   offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
 +   + CHANNEL_SCAN_INDEX_X

Re: [PATCH v5 0/4] iio: Add support for rotation from north

2014-07-09 Thread Reyad Attiyat
Hey Srinivas,

I did look into the panic you sent. I wasn't sure exactly what caused
the NULL pointer.
I tested it with out applying the last rotation from north patch, so
no hid usages are found, my device only has rotation_from_north, and
hid_parse_report() would return -EINVAL.
I added another check to make sure a iio channel were set up, and
return -EINVAL if not, but couldn't think of anything else.

Could you test this version with dynamic debugging and see if it is
finding any hid usage attributes.
Any ideas what could cause this? I think I'm handling errors properly
by returning what parse_report returns (-EINVAL or -ENOMEM) in probe

Thanks,
Reyad Attiyat

On Wed, Jul 9, 2014 at 2:45 PM, Srinivas Pandruvada
srinivas.pandruv...@linux.intel.com wrote:
 On 07/09/2014 12:30 PM, Reyad Attiyat wrote:

 This series of patches modifies magn-3d driver to handle the rotation
 from north usage. This is done by scanning the report and then building
 the iio arrays (vals and channels) dynamically.

 Changes from V4
 I use the address field of struct iio_chan_spec to hold the array index
 of the usage attribute. The scan_index field is generated when creating
 an iio channel.

 Reyad Attiyat (4):
iio: Documentation: Add documentation for rotation from north sensor
  usage attributes
iio: types: Added support for rotation from north usage attributes
iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
  iio channels
iio: hid-sensor-magn-3d: Add support for rotation from north

   Documentation/ABI/testing/sysfs-bus-iio   |  82 +++
   drivers/iio/industrialio-core.c   |   4 +
   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 199
 --
   include/linux/iio/types.h |   4 +
   4 files changed, 245 insertions(+), 44 deletions(-)

 Did you get chance to look at the cause of panic?

 Thanks,
 Srinivas
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-08 Thread Reyad Attiyat
Hello Srinivas,

Thanks for testing this patch. I only have one PC with a
hid-sensor-hub and mine doesn't have the axis usage attribute only
north. I'll look into this.

On Mon, Jul 7, 2014 at 2:58 PM, Srinivas Pandruvada
 wrote:
> Hi Reyad,
>
> I see panic in the probe function. Can you review your logic?
> It is possible that platforms don't have all attributes, so looks
> like the probe is returnning with error.
>
>
> On 07/07/2014 09:44 AM, Jonathan Cameron wrote:
>>
>> On 30/06/14 03:58, Reyad Attiyat wrote:
>>>
>>> Scan for and count the HID usage attributes supported by the driver.
>>> This allows for the driver to only setup the IIO channels for the
>>> sensor usages present in the HID USB reports.
>>>
>>> Signed-off-by: Reyad Attiyat 
>>> ---
>>
>> There should be an explanation here of what has changed from one version
>> to the
>> next.
>>
>> The patches should have been run through checkpatch.pl (at least one
>> place below
>> indicates that didn't happen).
>>
>> Mostly little bits left.  Now I would definitely like an ack or
>> reviewed-by
>> from Srinivas for this one if at all possible.
>
>
> [7.653643] BUG: unable to handle kernel NULL pointer dereference at
> 0031
> [7.653648] IP: [] sysfs_remove_link+0xe/0x30
> [7.653650] PGD 13d0fd067 PUD 147cbd067 PMD 0
> [7.653652] Oops:  [#1] SMP
> [7.653676] Modules linked in: hid_sensor_magn_3d(+) hid_sensor_rotation
> hid_sensor_gyro_3d hid_sensor_trigger industrialio_triggered_buffer
> kfifo_buf industrialio asix(+) usb_storage hid_sensor_iio_common usbnet
> usbhid mii joydev usbserial(+) hid_rmi(+) intel_rapl x86_pkg_temp_thermal
> uvcvideo intel_powerclamp coretemp kvm_intel videobuf2_vmalloc
> videobuf2_memops videobuf2_core iwlwifi kvm v4l2_common videodev
> hid_multitouch hid_sensor_hub ppdev btusb crct10dif_pclmul cfg80211
> crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul
> glue_helper ablk_helper cryptd mei_me(+) mei serio_raw lpc_ich(+) i915(+)
> snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_controller
> snd_hda_codec snd_hwdep snd_pcm snd_seq_midi drm_kms_helper
> snd_seq_midi_event snd_rawmidi snd_seq drm snd_seq_device snd_timer snd
> soundcore i2c_algo_bit mac_hid nfsd i2c_hid hid auth_rpcgss nfs_acl rfcomm
> nfs bnep bluetooth lockd winbond_cir sunrpc rc_core parport_pc dw_dmac
> dw_dmac_core video i2c_designware_platform spi_pxa2xx_platform
> i2c_designware_core binfmt_misc 8250_dw fscache lp nls_iso8859_1 parport
> ahci libahci sdhci_acpi sdhci
> [7.653691] CPU: 1 PID: 372 Comm: systemd-udevd Not tainted 3.16.0-rc4+
> #27
> [7.653692] Hardware name: Intel Corporation Shark Bay Client
> platform/Harris Beach SDS, BIOS HSWLPTU1.86C.0133.R00.1309172123 09/17/2013
> [7.653693] task: 880148584b60 ti: 880148914000 task.ti:
> 880148914000
> [7.653696] RIP: 0010:[]  []
> sysfs_remove_link+0xe/0x30
> [7.653697] RSP: 0018:880148917c30  EFLAGS: 00010202
> [7.653698] RAX: a08a1028 RBX: 880090bef810 RCX:
> 1043
> [7.653698] RDX: 1042 RSI:  RDI:
> 0001
> [7.653699] RBP: 880148917c30 R08: 000171c0 R09:
> 88014f2571c0
> [7.653700] R10: ea0002ac20c0 R11: 814a48a9 R12:
> fff0
> [7.653701] R13: a08a1028 R14: 0025 R15:
> 0001
> [7.653702] FS:  7fd70e437880() GS:88014f24()
> knlGS:
> [7.653703] CS:  0010 DS:  ES:  CR0: 80050033
> [7.653704] CR2: 0031 CR3: 00013d05e000 CR4:
> 001407e0
> [7.653705] DR0:  DR1:  DR2:
> 
> [7.653706] DR3:  DR6: fffe0ff0 DR7:
> 0400
> [7.653706] Stack:
> [7.653708]  880148917c48 814a0626 880090bef810
> 880148917c78
> [7.653710]  814a0c2e 880090bef810 a08a1028
> 880090bef870
> [7.653712]   880148917ca0 814a1053
> 
> [7.653712] Call Trace:
> [7.653716]  [] driver_sysfs_remove+0x26/0x40
> [7.653719]  [] driver_probe_device+0x8e/0x3e0
> [7.653720]  [] __driver_attach+0x93/0xa0
> [7.653722]  [] ? __device_attach+0x40/0x40
> [7.653725]  [] bus_for_each_dev+0x63/0xa0
> [7.653727]  [] driver_attach+0x1e/0x20
> [7.653728]  [] bus_add_driver+0x180/0x250
> [7.653731]  [] ? 0xa005afff
> [7.653733]  [] driver_register+0x64/0xf0
> [7.653735]  [] __platform_driver_reg

Re: [PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-08 Thread Reyad Attiyat
Hey Jonathan,

Thanks for the review. I'll be sure to fix up all the formatting you
mentioned and run it through the checkpatch.pl script.

> There should be an explanation here of what has changed from one version to
> the
> next.
Will include updates in future patch notes.

> The patches should have been run through checkpatch.pl (at least one place
> below
> indicates that didn't happen).
>
> Mostly little bits left.  Now I would definitely like an ack or reviewed-by
> from Srinivas for this one if at all possible.
> Any tested-bys, particularly with parts that don't have the new channel
> types, would also be good.
>
> Jonathan
>
>>   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 111
>> +-
>>   1 file changed, 75 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> index 41cf29e..070d20e 100644
>> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> @@ -42,7 +42,8 @@ struct magn_3d_state {
>> struct hid_sensor_hub_callbacks callbacks;
>> struct hid_sensor_common common_attributes;
>> struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
>> -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
>> +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
>> +   u32 *iio_val;
>> int scale_pre_decml;
>> int scale_post_decml;
>> int scale_precision;
>> @@ -221,8 +222,8 @@ static int magn_3d_proc_event(struct
>> hid_sensor_hub_device *hsdev,
>> dev_dbg(_dev->dev, "magn_3d_proc_event\n");
>> if (atomic_read(_state->common_attributes.data_ready))
>> hid_sensor_push_data(indio_dev,
>> -   magn_state->magn_val,
>> -   sizeof(magn_state->magn_val));
>> +   magn_state->iio_val,
>> +   sizeof(magn_state->iio_val));
>>
>> return 0;
>>   }
>> @@ -236,52 +237,99 @@ static int magn_3d_capture_sample(struct
>> hid_sensor_hub_device *hsdev,
>> struct iio_dev *indio_dev = platform_get_drvdata(priv);
>> struct magn_3d_state *magn_state = iio_priv(indio_dev);
>> int offset;
>> -   int ret = -EINVAL;
>> +   int ret = 0;
>> +   u32 *iio_val = NULL;
>
> This has me a little confused.  You have an iio_val in your state
> structure and in this function.  I can't actually find anywhere where
> the elements of the one in the state structure are ever assigned to
> anything.
>
>

I assign the pointer location of iio_vals to:
 u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];

I also added this array just for the locations. The assignment occurs
in the parse_report
function, after iio_vals is allocated, like this  st->magn_val_addr[i]
= &(st->iio_val[*chan_count]).
I'll add a comment to explain the usage better.


>>
>> switch (usage_id) {
>> case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
>> case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
>> case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
>> offset = usage_id -
>> HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
>> -   magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
>> -   *(u32 *)raw_data;
>> -   ret = 0;
>> +   iio_val = magn_state->magn_val_addr[CHANNEL_SCAN_INDEX_X +
>> offset];
>> +
>> break;
>> default:
>> -   break;
>> +   return -EINVAL;
>> }
>>
>> +   if(iio_val)
>
> white space after if please.
>
>> +   *iio_val = *(u32 *)raw_data;
>> +   else
>> +   ret = -EINVAL;
>> +
>> return ret;
>>   }
>>
>>   /* Parse report which is specific to an usage id*/
>>   static int magn_3d_parse_report(struct platform_device *pdev,
>> struct hid_sensor_hub_device *hsdev,
>> -   struct iio_chan_spec *channels,
>> +   struct iio_chan_spec **channels,
>> +   int *chan_count,
>> unsigned usage_id,
>> struct magn_3d_state *st)
>>   {
>> -   int ret;
>> +   int ret = 0;
>> int i;
>> +   int attr_count = 0;
>> +
>> +   /* Scan for each usage attribute supported */
>> +   for (i = 0; i < MAGN_3D_CHANNEL_MAX; i++) {
>> +   u32 address = magn_3d_addresses[i];
>>
>> -   for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
>> +   /* Check if usage attribute exists in the sensor hub
>> device */
>> ret = sensor_hub_input_get_attribute_info(hsdev,
>> -   HID_INPUT_REPORT,
>> -   usage_id,
>> -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS +
>> i,
>> -   

Re: [PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-08 Thread Reyad Attiyat
Hey Jonathan,

Thanks for the review. I'll be sure to fix up all the formatting you
mentioned and run it through the checkpatch.pl script.

 There should be an explanation here of what has changed from one version to
 the
 next.
Will include updates in future patch notes.

 The patches should have been run through checkpatch.pl (at least one place
 below
 indicates that didn't happen).

 Mostly little bits left.  Now I would definitely like an ack or reviewed-by
 from Srinivas for this one if at all possible.
 Any tested-bys, particularly with parts that don't have the new channel
 types, would also be good.

 Jonathan

   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 111
 +-
   1 file changed, 75 insertions(+), 36 deletions(-)

 diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 index 41cf29e..070d20e 100644
 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 @@ -42,7 +42,8 @@ struct magn_3d_state {
 struct hid_sensor_hub_callbacks callbacks;
 struct hid_sensor_common common_attributes;
 struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
 -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
 +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
 +   u32 *iio_val;
 int scale_pre_decml;
 int scale_post_decml;
 int scale_precision;
 @@ -221,8 +222,8 @@ static int magn_3d_proc_event(struct
 hid_sensor_hub_device *hsdev,
 dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
 if (atomic_read(magn_state-common_attributes.data_ready))
 hid_sensor_push_data(indio_dev,
 -   magn_state-magn_val,
 -   sizeof(magn_state-magn_val));
 +   magn_state-iio_val,
 +   sizeof(magn_state-iio_val));

 return 0;
   }
 @@ -236,52 +237,99 @@ static int magn_3d_capture_sample(struct
 hid_sensor_hub_device *hsdev,
 struct iio_dev *indio_dev = platform_get_drvdata(priv);
 struct magn_3d_state *magn_state = iio_priv(indio_dev);
 int offset;
 -   int ret = -EINVAL;
 +   int ret = 0;
 +   u32 *iio_val = NULL;

 This has me a little confused.  You have an iio_val in your state
 structure and in this function.  I can't actually find anywhere where
 the elements of the one in the state structure are ever assigned to
 anything.



I assign the pointer location of iio_vals to:
 u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];

I also added this array just for the locations. The assignment occurs
in the parse_report
function, after iio_vals is allocated, like this  st-magn_val_addr[i]
= (st-iio_val[*chan_count]).
I'll add a comment to explain the usage better.



 switch (usage_id) {
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
 offset = usage_id -
 HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
 -   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
 -   *(u32 *)raw_data;
 -   ret = 0;
 +   iio_val = magn_state-magn_val_addr[CHANNEL_SCAN_INDEX_X +
 offset];
 +
 break;
 default:
 -   break;
 +   return -EINVAL;
 }

 +   if(iio_val)

 white space after if please.

 +   *iio_val = *(u32 *)raw_data;
 +   else
 +   ret = -EINVAL;
 +
 return ret;
   }

   /* Parse report which is specific to an usage id*/
   static int magn_3d_parse_report(struct platform_device *pdev,
 struct hid_sensor_hub_device *hsdev,
 -   struct iio_chan_spec *channels,
 +   struct iio_chan_spec **channels,
 +   int *chan_count,
 unsigned usage_id,
 struct magn_3d_state *st)
   {
 -   int ret;
 +   int ret = 0;
 int i;
 +   int attr_count = 0;
 +
 +   /* Scan for each usage attribute supported */
 +   for (i = 0; i  MAGN_3D_CHANNEL_MAX; i++) {
 +   u32 address = magn_3d_addresses[i];

 -   for (i = 0; i = CHANNEL_SCAN_INDEX_Z; ++i) {
 +   /* Check if usage attribute exists in the sensor hub
 device */
 ret = sensor_hub_input_get_attribute_info(hsdev,
 -   HID_INPUT_REPORT,
 -   usage_id,
 -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS +
 i,
 -   st-magn[CHANNEL_SCAN_INDEX_X + i]);
 -   if (ret  0)
 -   break;
 -   magn_3d_adjust_channel_bit_mask(channels,
 -   CHANNEL_SCAN_INDEX_X + i,
 

Re: [PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-07-08 Thread Reyad Attiyat
Hello Srinivas,

Thanks for testing this patch. I only have one PC with a
hid-sensor-hub and mine doesn't have the axis usage attribute only
north. I'll look into this.

On Mon, Jul 7, 2014 at 2:58 PM, Srinivas Pandruvada
srinivas.pandruv...@linux.intel.com wrote:
 Hi Reyad,

 I see panic in the probe function. Can you review your logic?
 It is possible that platforms don't have all attributes, so looks
 like the probe is returnning with error.


 On 07/07/2014 09:44 AM, Jonathan Cameron wrote:

 On 30/06/14 03:58, Reyad Attiyat wrote:

 Scan for and count the HID usage attributes supported by the driver.
 This allows for the driver to only setup the IIO channels for the
 sensor usages present in the HID USB reports.

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---

 There should be an explanation here of what has changed from one version
 to the
 next.

 The patches should have been run through checkpatch.pl (at least one
 place below
 indicates that didn't happen).

 Mostly little bits left.  Now I would definitely like an ack or
 reviewed-by
 from Srinivas for this one if at all possible.


 [7.653643] BUG: unable to handle kernel NULL pointer dereference at
 0031
 [7.653648] IP: [81242cee] sysfs_remove_link+0xe/0x30
 [7.653650] PGD 13d0fd067 PUD 147cbd067 PMD 0
 [7.653652] Oops:  [#1] SMP
 [7.653676] Modules linked in: hid_sensor_magn_3d(+) hid_sensor_rotation
 hid_sensor_gyro_3d hid_sensor_trigger industrialio_triggered_buffer
 kfifo_buf industrialio asix(+) usb_storage hid_sensor_iio_common usbnet
 usbhid mii joydev usbserial(+) hid_rmi(+) intel_rapl x86_pkg_temp_thermal
 uvcvideo intel_powerclamp coretemp kvm_intel videobuf2_vmalloc
 videobuf2_memops videobuf2_core iwlwifi kvm v4l2_common videodev
 hid_multitouch hid_sensor_hub ppdev btusb crct10dif_pclmul cfg80211
 crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul
 glue_helper ablk_helper cryptd mei_me(+) mei serio_raw lpc_ich(+) i915(+)
 snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_controller
 snd_hda_codec snd_hwdep snd_pcm snd_seq_midi drm_kms_helper
 snd_seq_midi_event snd_rawmidi snd_seq drm snd_seq_device snd_timer snd
 soundcore i2c_algo_bit mac_hid nfsd i2c_hid hid auth_rpcgss nfs_acl rfcomm
 nfs bnep bluetooth lockd winbond_cir sunrpc rc_core parport_pc dw_dmac
 dw_dmac_core video i2c_designware_platform spi_pxa2xx_platform
 i2c_designware_core binfmt_misc 8250_dw fscache lp nls_iso8859_1 parport
 ahci libahci sdhci_acpi sdhci
 [7.653691] CPU: 1 PID: 372 Comm: systemd-udevd Not tainted 3.16.0-rc4+
 #27
 [7.653692] Hardware name: Intel Corporation Shark Bay Client
 platform/Harris Beach SDS, BIOS HSWLPTU1.86C.0133.R00.1309172123 09/17/2013
 [7.653693] task: 880148584b60 ti: 880148914000 task.ti:
 880148914000
 [7.653696] RIP: 0010:[81242cee]  [81242cee]
 sysfs_remove_link+0xe/0x30
 [7.653697] RSP: 0018:880148917c30  EFLAGS: 00010202
 [7.653698] RAX: a08a1028 RBX: 880090bef810 RCX:
 1043
 [7.653698] RDX: 1042 RSI:  RDI:
 0001
 [7.653699] RBP: 880148917c30 R08: 000171c0 R09:
 88014f2571c0
 [7.653700] R10: ea0002ac20c0 R11: 814a48a9 R12:
 fff0
 [7.653701] R13: a08a1028 R14: 0025 R15:
 0001
 [7.653702] FS:  7fd70e437880() GS:88014f24()
 knlGS:
 [7.653703] CS:  0010 DS:  ES:  CR0: 80050033
 [7.653704] CR2: 0031 CR3: 00013d05e000 CR4:
 001407e0
 [7.653705] DR0:  DR1:  DR2:
 
 [7.653706] DR3:  DR6: fffe0ff0 DR7:
 0400
 [7.653706] Stack:
 [7.653708]  880148917c48 814a0626 880090bef810
 880148917c78
 [7.653710]  814a0c2e 880090bef810 a08a1028
 880090bef870
 [7.653712]   880148917ca0 814a1053
 
 [7.653712] Call Trace:
 [7.653716]  [814a0626] driver_sysfs_remove+0x26/0x40
 [7.653719]  [814a0c2e] driver_probe_device+0x8e/0x3e0
 [7.653720]  [814a1053] __driver_attach+0x93/0xa0
 [7.653722]  [814a0fc0] ? __device_attach+0x40/0x40
 [7.653725]  [8149ec93] bus_for_each_dev+0x63/0xa0
 [7.653727]  [814a06ce] driver_attach+0x1e/0x20
 [7.653728]  [814a02e0] bus_add_driver+0x180/0x250
 [7.653731]  [a005b000] ? 0xa005afff
 [7.653733]  [814a1834] driver_register+0x64/0xf0
 [7.653735]  [814a2dca] __platform_driver_register+0x4a/0x50
 [7.653737]  [a005b017]
 hid_magn_3d_platform_driver_init+0x17/0x1000 [hid_sensor_magn_3d]
 [7.653741]  [8100212c] do_one_initcall+0xbc/0x1f0
 [7.653744]  [811b239d] ? kfree+0xfd/0x140

[PATCH v4 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-06-29 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 58 ++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 070d20e..69f8ac9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -53,7 +57,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -88,6 +96,46 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_Z,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE,
}
 };
 
@@ -248,6 +296,14 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
iio_val = magn_state->magn_val_addr[CHANNEL_SCAN_INDEX_X + 
offset];
 
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH;
+   iio_val = 
magn_state->magn_val_addr[CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP + offset];
+
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-06-29 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 111 +-
 1 file changed, 75 insertions(+), 36 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..070d20e 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,8 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+   u32 *iio_val;
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -221,8 +222,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state->magn_val,
-   sizeof(magn_state->magn_val));
+   magn_state->iio_val,
+   sizeof(magn_state->iio_val));
 
return 0;
 }
@@ -236,52 +237,99 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   iio_val = magn_state->magn_val_addr[CHANNEL_SCAN_INDEX_X + 
offset];
+
break;
default:
-   break;
+   return -EINVAL;
}
 
+   if(iio_val)
+   *iio_val = *(u32 *)raw_data;
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   struct iio_chan_spec *channels,
+   struct iio_chan_spec **channels,
+   int *chan_count,
unsigned usage_id,
struct magn_3d_state *st)
 {
-   int ret;
+   int ret = 0;
int i;
+   int attr_count = 0;
+
+   /* Scan for each usage attribute supported */
+   for (i = 0; i < MAGN_3D_CHANNEL_MAX; i++) {
+   u32 address = magn_3d_addresses[i];
 
-   for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
+   /* Check if usage attribute exists in the sensor hub device */
ret = sensor_hub_input_get_attribute_info(hsdev,
-   HID_INPUT_REPORT,
-   usage_id,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS + i,
-   >magn[CHANNEL_SCAN_INDEX_X + i]);
-   if (ret < 0)
-   break;
-   magn_3d_adjust_channel_bit_mask(channels,
-   CHANNEL_SCAN_INDEX_X + i,
-   st->magn[CHANNEL_SCAN_INDEX_X + i].size);
+   HID_INPUT_REPORT,
+   usage_id,
+   address,
+   &(st->magn[i]));
+   if (!ret)
+   attr_count++;
}
-   dev_dbg(>dev, "magn_3d %x:%x, %x:%x, %x:%x\n",
+
+   dev_dbg(>dev, "magn_3d Found %d usage attributes\n",
+   attr_count);
+   dev_dbg(>dev, "magn_3d X: %x:%x Y: %x:%x Z: %x:%x\n",
st->magn[0].index,
st->magn[0].report_id,
st->magn[1].index, st->magn[1].report_id,
st->magn[2].index, st->magn[2].report_id);
 
+   if (attr_count > 0)
+   ret = 0;
+   else
+   return  -EINVAL;
+
+   /* Setup IIO channel array */
+   *channels = devm_kc

[PATCH v4 2/4] iio: types: Added support for rotation from north usage attributes

2014-06-29 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+   [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+   [IIO_MOD_NORTH_TRUE] = "from_north_true",
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-06-29 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat 
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..e88833d 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value
@@ -588,6 +616,18

[PATCH v4 0/4] Add support for rotation from north to the hid-sensor-magn-3d driver

2014-06-29 Thread Reyad Attiyat
This version of patches tries to make smaller changes to the magn-3d driver. It
scans for usages present in the magn_3d_addresses array. It then allocates
memory for the IIO channel structs and value arrays that are used in the IIO 
subsystem.
It sets-up each IIO channel struct by copying the values from the static array 
of
IIO configurations. There is also an array used to store each channel IIO value
pointer for each HID usage attribute.



Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 167 --
 include/linux/iio/types.h |   4 +
 4 files changed, 220 insertions(+), 37 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 1/4] iio: Documentation: Add documentation for rotation from north sensor usage attributes

2014-06-29 Thread Reyad Attiyat
Added documentation for the sysfs attributes supported by the rotation from 
north
sensor.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 Documentation/ABI/testing/sysfs-bus-iio | 82 +
 1 file changed, 82 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..e88833d 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value

[PATCH v4 0/4] Add support for rotation from north to the hid-sensor-magn-3d driver

2014-06-29 Thread Reyad Attiyat
This version of patches tries to make smaller changes to the magn-3d driver. It
scans for usages present in the magn_3d_addresses array. It then allocates
memory for the IIO channel structs and value arrays that are used in the IIO 
subsystem.
It sets-up each IIO channel struct by copying the values from the static array 
of
IIO configurations. There is also an array used to store each channel IIO value
pointer for each HID usage attribute.



Reyad Attiyat (4):
  iio: Documentation: Add documentation for rotation from north sensor
usage attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Scan for usage attributes before setting up
iio channels
  iio: hid-sensor-magn-3d: Add support for rotation from north

 Documentation/ABI/testing/sysfs-bus-iio   |  82 +
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 167 --
 include/linux/iio/types.h |   4 +
 4 files changed, 220 insertions(+), 37 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 4/4] iio: hid-sensor-magn-3d: Add support for rotation from north

2014-06-29 Thread Reyad Attiyat
Add the HID usage attribute ID's and IIO channel info for rotation
from north support.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 58 ++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 070d20e..69f8ac9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -53,7 +57,11 @@ struct magn_3d_state {
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+   HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+   HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+   HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
 };
 
 /* Channel definitions */
@@ -88,6 +96,46 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_Z,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_MAGN,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE,
+   }, {
+   .type = IIO_ROT,
+   .modified = 1,
+   .channel2 = IIO_MOD_NORTH_TRUE,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+   BIT(IIO_CHAN_INFO_SCALE) |
+   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+   BIT(IIO_CHAN_INFO_HYSTERESIS),
+   .scan_index = CHANNEL_SCAN_INDEX_NORTH_TRUE,
}
 };
 
@@ -248,6 +296,14 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
iio_val = magn_state-magn_val_addr[CHANNEL_SCAN_INDEX_X + 
offset];
 
break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH;
+   iio_val = 
magn_state-magn_val_addr[CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP + offset];
+
+   break;
default:
return -EINVAL;
}
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 3/4] iio: hid-sensor-magn-3d: Scan for usage attributes before setting up iio channels

2014-06-29 Thread Reyad Attiyat
Scan for and count the HID usage attributes supported by the driver.
This allows for the driver to only setup the IIO channels for the
sensor usages present in the HID USB reports.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 111 +-
 1 file changed, 75 insertions(+), 36 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..070d20e 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -42,7 +42,8 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+   u32 *iio_val;
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -221,8 +222,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
dev_dbg(indio_dev-dev, magn_3d_proc_event\n);
if (atomic_read(magn_state-common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
-   magn_state-magn_val,
-   sizeof(magn_state-magn_val));
+   magn_state-iio_val,
+   sizeof(magn_state-iio_val));
 
return 0;
 }
@@ -236,52 +237,99 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
-   int ret = -EINVAL;
+   int ret = 0;
+   u32 *iio_val = NULL;
 
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
-   magn_state-magn_val[CHANNEL_SCAN_INDEX_X + offset] =
-   *(u32 *)raw_data;
-   ret = 0;
+   iio_val = magn_state-magn_val_addr[CHANNEL_SCAN_INDEX_X + 
offset];
+
break;
default:
-   break;
+   return -EINVAL;
}
 
+   if(iio_val)
+   *iio_val = *(u32 *)raw_data;
+   else
+   ret = -EINVAL;
+
return ret;
 }
 
 /* Parse report which is specific to an usage id*/
 static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
-   struct iio_chan_spec *channels,
+   struct iio_chan_spec **channels,
+   int *chan_count,
unsigned usage_id,
struct magn_3d_state *st)
 {
-   int ret;
+   int ret = 0;
int i;
+   int attr_count = 0;
+
+   /* Scan for each usage attribute supported */
+   for (i = 0; i  MAGN_3D_CHANNEL_MAX; i++) {
+   u32 address = magn_3d_addresses[i];
 
-   for (i = 0; i = CHANNEL_SCAN_INDEX_Z; ++i) {
+   /* Check if usage attribute exists in the sensor hub device */
ret = sensor_hub_input_get_attribute_info(hsdev,
-   HID_INPUT_REPORT,
-   usage_id,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS + i,
-   st-magn[CHANNEL_SCAN_INDEX_X + i]);
-   if (ret  0)
-   break;
-   magn_3d_adjust_channel_bit_mask(channels,
-   CHANNEL_SCAN_INDEX_X + i,
-   st-magn[CHANNEL_SCAN_INDEX_X + i].size);
+   HID_INPUT_REPORT,
+   usage_id,
+   address,
+   (st-magn[i]));
+   if (!ret)
+   attr_count++;
}
-   dev_dbg(pdev-dev, magn_3d %x:%x, %x:%x, %x:%x\n,
+
+   dev_dbg(pdev-dev, magn_3d Found %d usage attributes\n,
+   attr_count);
+   dev_dbg(pdev-dev, magn_3d X: %x:%x Y: %x:%x Z: %x:%x\n,
st-magn[0].index,
st-magn[0].report_id,
st-magn[1].index, st-magn[1].report_id,
st-magn[2].index, st-magn[2].report_id);
 
+   if (attr_count  0)
+   ret = 0;
+   else
+   return  -EINVAL;
+
+   /* Setup IIO channel array */
+   *channels = devm_kcalloc(pdev-dev, attr_count,
+   sizeof(struct 
iio_chan_spec

[PATCH v4 2/4] iio: types: Added support for rotation from north usage attributes

2014-06-29 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = quaternion,
[IIO_MOD_TEMP_AMBIENT] = ambient,
[IIO_MOD_TEMP_OBJECT] = object,
+   [IIO_MOD_NORTH_MAGN] = from_north_magnetic,
+   [IIO_MOD_NORTH_TRUE] = from_north_true,
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = from_north_magnetic_tilt_comp,
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = from_north_true_tilt_comp,
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/3] IIO: Add support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
These patches add support for rotation from north HID usage attributes to
the magnetometer 3d driver.

Changes from v2:
Use devm_kcalloc for all dynamic allocations
Cleanup formatting of if statements
Scan for the usage attributes present then dynamically allocate iio 
channel and value arrays
Use proper return errors (-EINVAL) and (-ENOMEM)


Reyad Attiyat (3):
  iio: documentation: Added documentation for rotation from north usage
attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Add support for rotation from north usage
attributes

 Documentation/ABI/testing/sysfs-bus-iio   |  79 +-
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 394 +-
 include/linux/iio/types.h |   4 +
 4 files changed, 352 insertions(+), 129 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/3] iio: documentation: Added documentation for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added documentation for the sysfs attributes added by the rotation from north
usage attributes.

Signed-off-by: Reyad Attiyat 
---
 Documentation/ABI/testing/sysfs-bus-iio | 79 -
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..2837fd9 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_raw_thresh_rising_value

[PATCH v3 2/3] iio: types: Added support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+   [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+   [IIO_MOD_NORTH_TRUE] = "from_north_true",
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] iio: hid-sensor-magn-3d: Add support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added the ability for this driver to scan for a range of hid usage attributes.
This allows for dynamic creation of iio channels such as rotation from north
and/or magnetic flux axises (X, Y, Z).

Signed-off-by: Reyad Attiyat 
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 394 +-
 1 file changed, 266 insertions(+), 128 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..73e1272 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -42,63 +46,47 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+   u32 *iio_val;
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
int value_offset;
 };
 
-static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
-};
 
-/* Channel definitions */
-static const struct iio_chan_spec magn_3d_channels[] = {
-   {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_X,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
-   }, {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_Y,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
-   }, {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_Z,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
+/* Find index into magn_3d_state magn[] and magn_val_addr[] from HID Usage  */
+static int magn_3d_usage_id_to_chan_index(unsigned usage_id){
+   int offset;
+
+   switch (usage_id) {
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
+   offset = CHANNEL_SCAN_INDEX_X;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
+   offset = CHANNEL_SCAN_INDEX_Y;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
+   offset = CHANNEL_SCAN_INDEX_Z;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_MAGN;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE;
+   break;
+   default:
+   offset = -EINVAL;
+   break;
}
-};
 
-/* Adjust channel real bits based on report descriptor */
-static void magn_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
-   int channel, int size)
-{
-   channels[channel].scan_type.sign = 's';
-   /* Real storage bits will change based on the report desc. */
-   channels[channel].scan_type.realbits = size * 8;
-   /* Maximum size of a sample to capture is u32 */
-   channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+   return offset;
 }
 
 /* Channel read_raw handler */
@@ -109,11 +97,14 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
 {
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int report_id = -1;
-   u32 address;
+   unsigned

[PATCH v3 2/3] iio: types: Added support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added the rotation from north usage attributes to the iio modifier enum and to 
the iio modifier names array.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/industrialio-core.c | 4 
 include/linux/iio/types.h   | 4 
 2 files changed, 8 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375..af3e76d 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = quaternion,
[IIO_MOD_TEMP_AMBIENT] = ambient,
[IIO_MOD_TEMP_OBJECT] = object,
+   [IIO_MOD_NORTH_MAGN] = from_north_magnetic,
+   [IIO_MOD_NORTH_TRUE] = from_north_true,
+   [IIO_MOD_NORTH_MAGN_TILT_COMP] = from_north_magnetic_tilt_comp,
+   [IIO_MOD_NORTH_TRUE_TILT_COMP] = from_north_true_tilt_comp,
 };
 
 /* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index d480631..d09c40d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -56,6 +56,10 @@ enum iio_modifier {
IIO_MOD_QUATERNION,
IIO_MOD_TEMP_AMBIENT,
IIO_MOD_TEMP_OBJECT,
+   IIO_MOD_NORTH_MAGN,
+   IIO_MOD_NORTH_TRUE,
+   IIO_MOD_NORTH_MAGN_TILT_COMP,
+   IIO_MOD_NORTH_TRUE_TILT_COMP
 };
 
 enum iio_event_type {
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] iio: hid-sensor-magn-3d: Add support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added the ability for this driver to scan for a range of hid usage attributes.
This allows for dynamic creation of iio channels such as rotation from north
and/or magnetic flux axises (X, Y, Z).

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 394 +-
 1 file changed, 266 insertions(+), 128 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e..73e1272 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE,
+   CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
MAGN_3D_CHANNEL_MAX,
 };
 
@@ -42,63 +46,47 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
-   u32 magn_val[MAGN_3D_CHANNEL_MAX];
+   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+   u32 *iio_val;
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
int value_offset;
 };
 
-static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
-   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
-};
 
-/* Channel definitions */
-static const struct iio_chan_spec magn_3d_channels[] = {
-   {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_X,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_X,
-   }, {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_Y,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Y,
-   }, {
-   .type = IIO_MAGN,
-   .modified = 1,
-   .channel2 = IIO_MOD_Z,
-   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
-   BIT(IIO_CHAN_INFO_SCALE) |
-   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
-   BIT(IIO_CHAN_INFO_HYSTERESIS),
-   .scan_index = CHANNEL_SCAN_INDEX_Z,
+/* Find index into magn_3d_state magn[] and magn_val_addr[] from HID Usage  */
+static int magn_3d_usage_id_to_chan_index(unsigned usage_id){
+   int offset;
+
+   switch (usage_id) {
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
+   offset = CHANNEL_SCAN_INDEX_X;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
+   offset = CHANNEL_SCAN_INDEX_Y;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
+   offset = CHANNEL_SCAN_INDEX_Z;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_MAGN;
+   break;
+   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE;
+   break;
+   default:
+   offset = -EINVAL;
+   break;
}
-};
 
-/* Adjust channel real bits based on report descriptor */
-static void magn_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
-   int channel, int size)
-{
-   channels[channel].scan_type.sign = 's';
-   /* Real storage bits will change based on the report desc. */
-   channels[channel].scan_type.realbits = size * 8;
-   /* Maximum size of a sample to capture is u32 */
-   channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+   return offset;
 }
 
 /* Channel read_raw handler */
@@ -109,11 +97,14 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
 {
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int report_id = -1;
-   u32

[PATCH v3 0/3] IIO: Add support for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
These patches add support for rotation from north HID usage attributes to
the magnetometer 3d driver.

Changes from v2:
Use devm_kcalloc for all dynamic allocations
Cleanup formatting of if statements
Scan for the usage attributes present then dynamically allocate iio 
channel and value arrays
Use proper return errors (-EINVAL) and (-ENOMEM)


Reyad Attiyat (3):
  iio: documentation: Added documentation for rotation from north usage
attributes
  iio: types: Added support for rotation from north usage attributes
  iio: hid-sensor-magn-3d: Add support for rotation from north usage
attributes

 Documentation/ABI/testing/sysfs-bus-iio   |  79 +-
 drivers/iio/industrialio-core.c   |   4 +
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 394 +-
 include/linux/iio/types.h |   4 +
 4 files changed, 352 insertions(+), 129 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/3] iio: documentation: Added documentation for rotation from north usage attributes

2014-06-16 Thread Reyad Attiyat
Added documentation for the sysfs attributes added by the rotation from north
usage attributes.

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 Documentation/ABI/testing/sysfs-bus-iio | 79 -
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio 
b/Documentation/ABI/testing/sysfs-bus-iio
index a9757dc..2837fd9 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -260,6 +260,10 @@ What:  
/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_scale
+What:  /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_scale
+What:  
/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:  /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 KernelVersion: 2.6.35
@@ -447,6 +451,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_thresh_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en
@@ -492,6 +504,14 @@ What:  
/sys/.../iio:deviceX/events/in_magn_y_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_roc_falling_en
+What:  /sys/.../iio:deviceX/events/in_rot_from_north_true_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_magnetic_tilt_comp_roc_falling_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_rising_en
+What:  
/sys/.../iio:deviceX/events/in_rot_from_north_true_tilt_comp_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en
 What:  /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en
@@ -538,6 +558,14 @@ What:  
/sys/.../events/in_magn_y_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_y_raw_thresh_falling_value
 What:  /sys/.../events/in_magn_z_raw_thresh_rising_value
 What:  /sys/.../events/in_magn_z_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_raw_thresh_falling_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_rising_value
+What:  /sys/.../events/in_rot_from_north_true_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_magnetic_tilt_comp_raw_thresh_falling_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_rising_value
+What:  
/sys/.../events/in_rot_from_north_true_tilt_comp_raw_thresh_falling_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_rising_value
 What:  /sys/.../events/in_voltageY_supply_raw_thresh_falling_value
 What:  /sys/.../events

Re: [PATCH] HID: hid-sensor-hub: Make all locks of dyn_callback_lock disable interrupts.

2014-06-10 Thread Reyad Attiyat
Hey Jiri,
I read your other email and see this is now staged. You can ignore
this sorry for the noise.

On Tue, Jun 10, 2014 at 3:11 PM, Reyad Attiyat  wrote:
> The dynamic callback lock (dyn_callback_lock) must not be interrupted
> when locked because the lock is used in the interrupt handler function 
> sensor_hub_raw_event().
>
> Signed-off-by: Reyad Attiyat 
> ---
>  drivers/hid/hid-sensor-hub.c | 31 ++-
>  1 file changed, 18 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
> index a8d5c8f..6547138 100644
> --- a/drivers/hid/hid-sensor-hub.c
> +++ b/drivers/hid/hid-sensor-hub.c
> @@ -133,10 +133,11 @@ static struct hid_sensor_hub_callbacks 
> *sensor_hub_get_callback(
> struct hid_sensor_hub_device **hsdev,
> void **priv)
>  {
> +   unsigned long flags;
> struct hid_sensor_hub_callbacks_list *callback;
> struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
>
> -   spin_lock(>dyn_callback_lock);
> +   spin_lock_irqsave(>dyn_callback_lock, flags);
> list_for_each_entry(callback, >dyn_callback_list, list)
> if (callback->usage_id == usage_id &&
> (collection_index >=
> @@ -145,10 +146,10 @@ static struct hid_sensor_hub_callbacks 
> *sensor_hub_get_callback(
> callback->hsdev->end_collection_index)) {
> *priv = callback->priv;
> *hsdev = callback->hsdev;
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, 
> flags);
> return callback->usage_callback;
> }
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, flags);
>
> return NULL;
>  }
> @@ -157,19 +158,20 @@ int sensor_hub_register_callback(struct 
> hid_sensor_hub_device *hsdev,
> u32 usage_id,
> struct hid_sensor_hub_callbacks *usage_callback)
>  {
> +   unsigned long flags;
> struct hid_sensor_hub_callbacks_list *callback;
> struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
>
> -   spin_lock(>dyn_callback_lock);
> +   spin_lock_irqsave(>dyn_callback_lock, flags);
> list_for_each_entry(callback, >dyn_callback_list, list)
> if (callback->usage_id == usage_id &&
> callback->hsdev == hsdev) {
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, 
> flags);
> return -EINVAL;
> }
> callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
> if (!callback) {
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, flags);
> return -ENOMEM;
> }
> callback->hsdev = hsdev;
> @@ -177,7 +179,7 @@ int sensor_hub_register_callback(struct 
> hid_sensor_hub_device *hsdev,
> callback->usage_id = usage_id;
> callback->priv = NULL;
> list_add_tail(>list, >dyn_callback_list);
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, flags);
>
> return 0;
>  }
> @@ -186,10 +188,11 @@ EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
>  int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
> u32 usage_id)
>  {
> +   unsigned long flags;
> struct hid_sensor_hub_callbacks_list *callback;
> struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
>
> -   spin_lock(>dyn_callback_lock);
> +   spin_lock_irqsave(>dyn_callback_lock, flags);
> list_for_each_entry(callback, >dyn_callback_list, list)
> if (callback->usage_id == usage_id &&
> callback->hsdev == hsdev) {
> @@ -197,7 +200,7 @@ int sensor_hub_remove_callback(struct 
> hid_sensor_hub_device *hsdev,
> kfree(callback);
> break;
> }
> -   spin_unlock(>dyn_callback_lock);
> +   spin_unlock_irqrestore(>dyn_callback_lock, flags);
>
> return 0;
>  }
> @@ -376,34 +379,36 @@ EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
>  #ifdef CONFIG

[PATCH] HID: hid-sensor-hub: Make all locks of dyn_callback_lock disable interrupts.

2014-06-10 Thread Reyad Attiyat
The dynamic callback lock (dyn_callback_lock) must not be interrupted
when locked because the lock is used in the interrupt handler function 
sensor_hub_raw_event().

Signed-off-by: Reyad Attiyat 
---
 drivers/hid/hid-sensor-hub.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index a8d5c8f..6547138 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -133,10 +133,11 @@ static struct hid_sensor_hub_callbacks 
*sensor_hub_get_callback(
struct hid_sensor_hub_device **hsdev,
void **priv)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
 
-   spin_lock(>dyn_callback_lock);
+   spin_lock_irqsave(>dyn_callback_lock, flags);
list_for_each_entry(callback, >dyn_callback_list, list)
if (callback->usage_id == usage_id &&
(collection_index >=
@@ -145,10 +146,10 @@ static struct hid_sensor_hub_callbacks 
*sensor_hub_get_callback(
callback->hsdev->end_collection_index)) {
*priv = callback->priv;
*hsdev = callback->hsdev;
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, 
flags);
return callback->usage_callback;
}
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, flags);
 
return NULL;
 }
@@ -157,19 +158,20 @@ int sensor_hub_register_callback(struct 
hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_hub_callbacks *usage_callback)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
 
-   spin_lock(>dyn_callback_lock);
+   spin_lock_irqsave(>dyn_callback_lock, flags);
list_for_each_entry(callback, >dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, 
flags);
return -EINVAL;
}
callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
if (!callback) {
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, flags);
return -ENOMEM;
}
callback->hsdev = hsdev;
@@ -177,7 +179,7 @@ int sensor_hub_register_callback(struct 
hid_sensor_hub_device *hsdev,
callback->usage_id = usage_id;
callback->priv = NULL;
list_add_tail(>list, >dyn_callback_list);
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, flags);
 
return 0;
 }
@@ -186,10 +188,11 @@ EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
 int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
u32 usage_id)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
 
-   spin_lock(>dyn_callback_lock);
+   spin_lock_irqsave(>dyn_callback_lock, flags);
list_for_each_entry(callback, >dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
@@ -197,7 +200,7 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device 
*hsdev,
kfree(callback);
break;
}
-   spin_unlock(>dyn_callback_lock);
+   spin_unlock_irqrestore(>dyn_callback_lock, flags);
 
return 0;
 }
@@ -376,34 +379,36 @@ EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
 #ifdef CONFIG_PM
 static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
 {
+   unsigned long flags;
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
struct hid_sensor_hub_callbacks_list *callback;
 
hid_dbg(hdev, " sensor_hub_suspend\n");
-   spin_lock(>dyn_callback_lock);
+   spin_lock_irqsave(>dyn_callback_lock, flags);
list_for_each_entry(callback, >dyn_callback_list, list) {
if (callback->usage_callback->suspend)
callback->usage_callback->suspend(
callback->hsdev, callback->

Re: [PATCHv2 3/3] IIO: hid-sensor-magn-3d: Add in support for True/Magnetic North HID usages

2014-06-10 Thread Reyad Attiyat
Hey Jonathan,

I will make the changes you suggested thanks for reviewing this. Any
conclusions on the naming, did you want me to change the sysfs name to
"in_rot_from_north_true/magnetic"?

On Mon, Jun 9, 2014 at 2:55 PM, Jonathan Cameron  wrote:
> On 03/06/14 00:14, Reyad Attiyat wrote:
>>
>> Updated magn_3d_channel enum for all possible north channels
>>
>> Added functions to setup iio_chan_spec array depending on which hid usage
>> reports are found
>>
>> Renamed magn_val to iio_val to differentiate the index being used
>>
>> Updated magn_3d_state struct to hold pointer array (magn_val_addr[]) which
>> points to iio_val[]
>>
>> Updated magn_3d_parse_report to scan for all compass usages and create iio
>> channels for each
>>
>> Signed-off-by: Reyad Attiyat 
>
> Hi Reyad,
>
> I've taken a rather quick look at this.  Will probably want to take
> one more close look at a newer version.
>
> Various bits and bobs inline - mostly fine!
> Jonathan
>
>> ---
>>   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 271
>> +-
>>   1 file changed, 177 insertions(+), 94 deletions(-)
>>
>> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> index 6d162b7..32f4d90 100644
>> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>> @@ -34,63 +34,54 @@ enum magn_3d_channel {
>> CHANNEL_SCAN_INDEX_X,
>> CHANNEL_SCAN_INDEX_Y,
>> CHANNEL_SCAN_INDEX_Z,
>> +   CHANNEL_SCAN_INDEX_NORTH_MAGN,
>> +   CHANNEL_SCAN_INDEX_NORTH_TRUE,
>> +   CHANNEL_SCAN_INDEX_NORTH_TILT_COMP,
>> +   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
>> MAGN_3D_CHANNEL_MAX,
>>   };
>>
>> +#define IIO_CHANNEL_MAX MAGN_3D_CHANNEL_MAX
>
> Please don't define a generic sounding name for a local
> constant.  Why not use MAGN_3D_CHANNEL_MAX everywhere?
>
>> +
>>   struct magn_3d_state {
>> struct hid_sensor_hub_callbacks callbacks;
>> struct hid_sensor_common common_attributes;
>> struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
>> -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
>> -};
>> +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
>>
>> -static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
>> -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
>> -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
>> -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
>> +   u32 iio_val[IIO_CHANNEL_MAX];
>> +   int num_iio_channels;
>>   };
>>
>> -/* Channel definitions */
>> -static const struct iio_chan_spec magn_3d_channels[] = {
>> -   {
>> -   .type = IIO_MAGN,
>> -   .modified = 1,
>> -   .channel2 = IIO_MOD_X,
>> -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
>> -   BIT(IIO_CHAN_INFO_SCALE) |
>> -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>> -   BIT(IIO_CHAN_INFO_HYSTERESIS),
>> -   .scan_index = CHANNEL_SCAN_INDEX_X,
>> -   }, {
>> -   .type = IIO_MAGN,
>> -   .modified = 1,
>> -   .channel2 = IIO_MOD_Y,
>> -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
>> -   BIT(IIO_CHAN_INFO_SCALE) |
>> -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>> -   BIT(IIO_CHAN_INFO_HYSTERESIS),
>> -   .scan_index = CHANNEL_SCAN_INDEX_Y,
>> -   }, {
>> -   .type = IIO_MAGN,
>> -   .modified = 1,
>> -   .channel2 = IIO_MOD_Z,
>> -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
>> -   BIT(IIO_CHAN_INFO_SCALE) |
>> -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>> -   BIT(IIO_CHAN_INFO_HYSTERESIS),
>> -   .scan_index = CHANNEL_SCAN_INDEX_Z,
>> +/* Find index into magn_3d_state magn[] and magn_val_addr[] from HID
>> Usage  */
>> +static int magn_3d_usage_id_to_chan_index(unsigned usage_id){
>> +   int offset = -1;
>
> I'd personally prefer offset = -EINVAL and to have it assigned as
> a default element in the switch statement rather that here.
>
>> +
>> +   switch (usage_id) {
>> +   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
>> +   offset = CHANNEL_SCAN_INDEX_X;
>> +   break;
>> +   case HID_US

Re: [PATCHv2 3/3] IIO: hid-sensor-magn-3d: Add in support for True/Magnetic North HID usages

2014-06-10 Thread Reyad Attiyat
Hey Jonathan,

I will make the changes you suggested thanks for reviewing this. Any
conclusions on the naming, did you want me to change the sysfs name to
in_rot_from_north_true/magnetic?

On Mon, Jun 9, 2014 at 2:55 PM, Jonathan Cameron ji...@kernel.org wrote:
 On 03/06/14 00:14, Reyad Attiyat wrote:

 Updated magn_3d_channel enum for all possible north channels

 Added functions to setup iio_chan_spec array depending on which hid usage
 reports are found

 Renamed magn_val to iio_val to differentiate the index being used

 Updated magn_3d_state struct to hold pointer array (magn_val_addr[]) which
 points to iio_val[]

 Updated magn_3d_parse_report to scan for all compass usages and create iio
 channels for each

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com

 Hi Reyad,

 I've taken a rather quick look at this.  Will probably want to take
 one more close look at a newer version.

 Various bits and bobs inline - mostly fine!
 Jonathan

 ---
   drivers/iio/magnetometer/hid-sensor-magn-3d.c | 271
 +-
   1 file changed, 177 insertions(+), 94 deletions(-)

 diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 index 6d162b7..32f4d90 100644
 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
 @@ -34,63 +34,54 @@ enum magn_3d_channel {
 CHANNEL_SCAN_INDEX_X,
 CHANNEL_SCAN_INDEX_Y,
 CHANNEL_SCAN_INDEX_Z,
 +   CHANNEL_SCAN_INDEX_NORTH_MAGN,
 +   CHANNEL_SCAN_INDEX_NORTH_TRUE,
 +   CHANNEL_SCAN_INDEX_NORTH_TILT_COMP,
 +   CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
 MAGN_3D_CHANNEL_MAX,
   };

 +#define IIO_CHANNEL_MAX MAGN_3D_CHANNEL_MAX

 Please don't define a generic sounding name for a local
 constant.  Why not use MAGN_3D_CHANNEL_MAX everywhere?

 +
   struct magn_3d_state {
 struct hid_sensor_hub_callbacks callbacks;
 struct hid_sensor_common common_attributes;
 struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
 -   u32 magn_val[MAGN_3D_CHANNEL_MAX];
 -};
 +   u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];

 -static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
 -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
 -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
 -   HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
 +   u32 iio_val[IIO_CHANNEL_MAX];
 +   int num_iio_channels;
   };

 -/* Channel definitions */
 -static const struct iio_chan_spec magn_3d_channels[] = {
 -   {
 -   .type = IIO_MAGN,
 -   .modified = 1,
 -   .channel2 = IIO_MOD_X,
 -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
 -   BIT(IIO_CHAN_INFO_SCALE) |
 -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 -   BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_X,
 -   }, {
 -   .type = IIO_MAGN,
 -   .modified = 1,
 -   .channel2 = IIO_MOD_Y,
 -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
 -   BIT(IIO_CHAN_INFO_SCALE) |
 -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 -   BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_Y,
 -   }, {
 -   .type = IIO_MAGN,
 -   .modified = 1,
 -   .channel2 = IIO_MOD_Z,
 -   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
 -   BIT(IIO_CHAN_INFO_SCALE) |
 -   BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 -   BIT(IIO_CHAN_INFO_HYSTERESIS),
 -   .scan_index = CHANNEL_SCAN_INDEX_Z,
 +/* Find index into magn_3d_state magn[] and magn_val_addr[] from HID
 Usage  */
 +static int magn_3d_usage_id_to_chan_index(unsigned usage_id){
 +   int offset = -1;

 I'd personally prefer offset = -EINVAL and to have it assigned as
 a default element in the switch statement rather that here.

 +
 +   switch (usage_id) {
 +   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
 +   offset = CHANNEL_SCAN_INDEX_X;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
 +   offset = CHANNEL_SCAN_INDEX_Y;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
 +   offset = CHANNEL_SCAN_INDEX_Z;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
 +   offset = CHANNEL_SCAN_INDEX_NORTH_TILT_COMP;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
 +   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
 +   offset = CHANNEL_SCAN_INDEX_NORTH_MAGN;
 +   break;
 +   case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
 +   offset = CHANNEL_SCAN_INDEX_NORTH_TRUE;
 +   break;
 }
 -};

 -/* Adjust

[PATCH] HID: hid-sensor-hub: Make all locks of dyn_callback_lock disable interrupts.

2014-06-10 Thread Reyad Attiyat
The dynamic callback lock (dyn_callback_lock) must not be interrupted
when locked because the lock is used in the interrupt handler function 
sensor_hub_raw_event().

Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
---
 drivers/hid/hid-sensor-hub.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index a8d5c8f..6547138 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -133,10 +133,11 @@ static struct hid_sensor_hub_callbacks 
*sensor_hub_get_callback(
struct hid_sensor_hub_device **hsdev,
void **priv)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
 
-   spin_lock(pdata-dyn_callback_lock);
+   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
list_for_each_entry(callback, pdata-dyn_callback_list, list)
if (callback-usage_id == usage_id 
(collection_index =
@@ -145,10 +146,10 @@ static struct hid_sensor_hub_callbacks 
*sensor_hub_get_callback(
callback-hsdev-end_collection_index)) {
*priv = callback-priv;
*hsdev = callback-hsdev;
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, 
flags);
return callback-usage_callback;
}
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);
 
return NULL;
 }
@@ -157,19 +158,20 @@ int sensor_hub_register_callback(struct 
hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_hub_callbacks *usage_callback)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev-hdev);
 
-   spin_lock(pdata-dyn_callback_lock);
+   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
list_for_each_entry(callback, pdata-dyn_callback_list, list)
if (callback-usage_id == usage_id 
callback-hsdev == hsdev) {
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, 
flags);
return -EINVAL;
}
callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
if (!callback) {
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);
return -ENOMEM;
}
callback-hsdev = hsdev;
@@ -177,7 +179,7 @@ int sensor_hub_register_callback(struct 
hid_sensor_hub_device *hsdev,
callback-usage_id = usage_id;
callback-priv = NULL;
list_add_tail(callback-list, pdata-dyn_callback_list);
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);
 
return 0;
 }
@@ -186,10 +188,11 @@ EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
 int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
u32 usage_id)
 {
+   unsigned long flags;
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev-hdev);
 
-   spin_lock(pdata-dyn_callback_lock);
+   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
list_for_each_entry(callback, pdata-dyn_callback_list, list)
if (callback-usage_id == usage_id 
callback-hsdev == hsdev) {
@@ -197,7 +200,7 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device 
*hsdev,
kfree(callback);
break;
}
-   spin_unlock(pdata-dyn_callback_lock);
+   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);
 
return 0;
 }
@@ -376,34 +379,36 @@ EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
 #ifdef CONFIG_PM
 static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
 {
+   unsigned long flags;
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
struct hid_sensor_hub_callbacks_list *callback;
 
hid_dbg(hdev,  sensor_hub_suspend\n);
-   spin_lock(pdata-dyn_callback_lock);
+   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
list_for_each_entry(callback, pdata-dyn_callback_list, list) {
if (callback-usage_callback-suspend)
callback-usage_callback-suspend(
callback-hsdev, callback-priv);
}
-   spin_unlock(pdata

Re: [PATCH] HID: hid-sensor-hub: Make all locks of dyn_callback_lock disable interrupts.

2014-06-10 Thread Reyad Attiyat
Hey Jiri,
I read your other email and see this is now staged. You can ignore
this sorry for the noise.

On Tue, Jun 10, 2014 at 3:11 PM, Reyad Attiyat reyad.atti...@gmail.com wrote:
 The dynamic callback lock (dyn_callback_lock) must not be interrupted
 when locked because the lock is used in the interrupt handler function 
 sensor_hub_raw_event().

 Signed-off-by: Reyad Attiyat reyad.atti...@gmail.com
 ---
  drivers/hid/hid-sensor-hub.c | 31 ++-
  1 file changed, 18 insertions(+), 13 deletions(-)

 diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
 index a8d5c8f..6547138 100644
 --- a/drivers/hid/hid-sensor-hub.c
 +++ b/drivers/hid/hid-sensor-hub.c
 @@ -133,10 +133,11 @@ static struct hid_sensor_hub_callbacks 
 *sensor_hub_get_callback(
 struct hid_sensor_hub_device **hsdev,
 void **priv)
  {
 +   unsigned long flags;
 struct hid_sensor_hub_callbacks_list *callback;
 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);

 -   spin_lock(pdata-dyn_callback_lock);
 +   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
 list_for_each_entry(callback, pdata-dyn_callback_list, list)
 if (callback-usage_id == usage_id 
 (collection_index =
 @@ -145,10 +146,10 @@ static struct hid_sensor_hub_callbacks 
 *sensor_hub_get_callback(
 callback-hsdev-end_collection_index)) {
 *priv = callback-priv;
 *hsdev = callback-hsdev;
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, 
 flags);
 return callback-usage_callback;
 }
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);

 return NULL;
  }
 @@ -157,19 +158,20 @@ int sensor_hub_register_callback(struct 
 hid_sensor_hub_device *hsdev,
 u32 usage_id,
 struct hid_sensor_hub_callbacks *usage_callback)
  {
 +   unsigned long flags;
 struct hid_sensor_hub_callbacks_list *callback;
 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev-hdev);

 -   spin_lock(pdata-dyn_callback_lock);
 +   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
 list_for_each_entry(callback, pdata-dyn_callback_list, list)
 if (callback-usage_id == usage_id 
 callback-hsdev == hsdev) {
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, 
 flags);
 return -EINVAL;
 }
 callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
 if (!callback) {
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);
 return -ENOMEM;
 }
 callback-hsdev = hsdev;
 @@ -177,7 +179,7 @@ int sensor_hub_register_callback(struct 
 hid_sensor_hub_device *hsdev,
 callback-usage_id = usage_id;
 callback-priv = NULL;
 list_add_tail(callback-list, pdata-dyn_callback_list);
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);

 return 0;
  }
 @@ -186,10 +188,11 @@ EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
  int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
 u32 usage_id)
  {
 +   unsigned long flags;
 struct hid_sensor_hub_callbacks_list *callback;
 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev-hdev);

 -   spin_lock(pdata-dyn_callback_lock);
 +   spin_lock_irqsave(pdata-dyn_callback_lock, flags);
 list_for_each_entry(callback, pdata-dyn_callback_list, list)
 if (callback-usage_id == usage_id 
 callback-hsdev == hsdev) {
 @@ -197,7 +200,7 @@ int sensor_hub_remove_callback(struct 
 hid_sensor_hub_device *hsdev,
 kfree(callback);
 break;
 }
 -   spin_unlock(pdata-dyn_callback_lock);
 +   spin_unlock_irqrestore(pdata-dyn_callback_lock, flags);

 return 0;
  }
 @@ -376,34 +379,36 @@ EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
  #ifdef CONFIG_PM
  static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
  {
 +   unsigned long flags;
 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
 struct hid_sensor_hub_callbacks_list *callback;

 hid_dbg(hdev,  sensor_hub_suspend\n);
 -   spin_lock(pdata-dyn_callback_lock);
 +   spin_lock_irqsave(pdata-dyn_callback_lock, flags

Re: [PATCHv2 3/3] IIO: hid-sensor-magn-3d: Add in support for True/Magnetic North HID usages

2014-06-04 Thread Reyad Attiyat
Hey Srinivas,

On Tue, Jun 3, 2014 at 12:43 PM, Srinivas Pandruvada
 wrote:

>
> May be we should have a field in const struct iio_chan_spec, so that we
> can dynamically enable disable channels. In this way we can statically
> define channels, but can be enabled/disabled dynamically.
>
Would this require changing iio subsystem to create sysfs entries only
when enabled? Would we need to add functions to disable and enable
later on?
>
> I think we need to present angle in radians. Are you basing change present
> in linux-next? This will automatically do in this function.
>
I'll look into this. What function should I use to make the iio chanel
to report radians?
>
>
> I don't see kfree. Try devm_kcalloc?
>
I changed kmemdup to kcalloc so there is still a kfree in the exsiting
code. I can change this to devm_kcalloc but only if we don't go with
static channels that are enabled as found.

Thanks,
Reyad Attiyat
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv2 3/3] IIO: hid-sensor-magn-3d: Add in support for True/Magnetic North HID usages

2014-06-04 Thread Reyad Attiyat
Hey Srinivas,

On Tue, Jun 3, 2014 at 12:43 PM, Srinivas Pandruvada
srinivas.pandruv...@linux.intel.com wrote:


 May be we should have a field in const struct iio_chan_spec, so that we
 can dynamically enable disable channels. In this way we can statically
 define channels, but can be enabled/disabled dynamically.

Would this require changing iio subsystem to create sysfs entries only
when enabled? Would we need to add functions to disable and enable
later on?

 I think we need to present angle in radians. Are you basing change present
 in linux-next? This will automatically do in this function.

I'll look into this. What function should I use to make the iio chanel
to report radians?


 I don't see kfree. Try devm_kcalloc?

I changed kmemdup to kcalloc so there is still a kfree in the exsiting
code. I can change this to devm_kcalloc but only if we don't go with
static channels that are enabled as found.

Thanks,
Reyad Attiyat
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   >