brintos

brintos / linux-shallow public Read only

0
0
Text · 21.3 KiB · 7bd86ee Raw
779 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * HID Sensors Driver4 * Copyright (c) 2012, Intel Corporation.5 */6 7#include <linux/device.h>8#include <linux/hid.h>9#include <linux/module.h>10#include <linux/slab.h>11#include <linux/mfd/core.h>12#include <linux/list.h>13#include <linux/hid-sensor-ids.h>14#include <linux/hid-sensor-hub.h>15#include "hid-ids.h"16 17#define HID_SENSOR_HUB_ENUM_QUIRK	0x0118 19/**20 * struct sensor_hub_data - Hold a instance data for a HID hub device21 * @mutex:		Mutex to serialize synchronous request.22 * @lock:		Spin lock to protect pending request structure.23 * @dyn_callback_list:	Holds callback function24 * @dyn_callback_lock:	spin lock to protect callback list25 * @hid_sensor_hub_client_devs:	Stores all MFD cells for a hub instance.26 * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).27 * @ref_cnt:		Number of MFD clients have opened this device28 */29struct sensor_hub_data {30	struct mutex mutex;31	spinlock_t lock;32	struct list_head dyn_callback_list;33	spinlock_t dyn_callback_lock;34	struct mfd_cell *hid_sensor_hub_client_devs;35	int hid_sensor_client_cnt;36	int ref_cnt;37};38 39/**40 * struct hid_sensor_hub_callbacks_list - Stores callback list41 * @list:		list head.42 * @usage_id:		usage id for a physical device.43 * @hsdev:		Stored hid instance for current hub device.44 * @usage_callback:	Stores registered callback functions.45 * @priv:		Private data for a physical device.46 */47struct hid_sensor_hub_callbacks_list {48	struct list_head list;49	u32 usage_id;50	struct hid_sensor_hub_device *hsdev;51	struct hid_sensor_hub_callbacks *usage_callback;52	void *priv;53};54 55static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,56						int dir)57{58	struct hid_report *report;59 60	list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) {61		if (report->id == id)62			return report;63	}64	hid_warn(hdev, "No report with id 0x%x found\n", id);65 66	return NULL;67}68 69static int sensor_hub_get_physical_device_count(struct hid_device *hdev)70{71	int i;72	int count = 0;73 74	for (i = 0; i < hdev->maxcollection; ++i) {75		struct hid_collection *collection = &hdev->collection[i];76		if (collection->type == HID_COLLECTION_PHYSICAL ||77		    collection->type == HID_COLLECTION_APPLICATION)78			++count;79	}80 81	return count;82}83 84static void sensor_hub_fill_attr_info(85		struct hid_sensor_hub_attribute_info *info,86		s32 index, s32 report_id, struct hid_field *field)87{88	info->index = index;89	info->report_id = report_id;90	info->units = field->unit;91	info->unit_expo = field->unit_exponent;92	info->size = (field->report_size * field->report_count)/8;93	info->logical_minimum = field->logical_minimum;94	info->logical_maximum = field->logical_maximum;95}96 97static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(98					struct hid_device *hdev,99					u32 usage_id,100					int collection_index,101					struct hid_sensor_hub_device **hsdev,102					void **priv)103{104	struct hid_sensor_hub_callbacks_list *callback;105	struct sensor_hub_data *pdata = hid_get_drvdata(hdev);106	unsigned long flags;107 108	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);109	list_for_each_entry(callback, &pdata->dyn_callback_list, list)110		if ((callback->usage_id == usage_id ||111		     callback->usage_id == HID_USAGE_SENSOR_COLLECTION) &&112			(collection_index >=113				callback->hsdev->start_collection_index) &&114			(collection_index <115				callback->hsdev->end_collection_index)) {116			*priv = callback->priv;117			*hsdev = callback->hsdev;118			spin_unlock_irqrestore(&pdata->dyn_callback_lock,119					       flags);120			return callback->usage_callback;121		}122	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);123 124	return NULL;125}126 127int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,128			u32 usage_id,129			struct hid_sensor_hub_callbacks *usage_callback)130{131	struct hid_sensor_hub_callbacks_list *callback;132	struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);133	unsigned long flags;134 135	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);136	list_for_each_entry(callback, &pdata->dyn_callback_list, list)137		if (callback->usage_id == usage_id &&138						callback->hsdev == hsdev) {139			spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);140			return -EINVAL;141		}142	callback = kzalloc(sizeof(*callback), GFP_ATOMIC);143	if (!callback) {144		spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);145		return -ENOMEM;146	}147	callback->hsdev = hsdev;148	callback->usage_callback = usage_callback;149	callback->usage_id = usage_id;150	callback->priv = NULL;151	/*152	 * If there is a handler registered for the collection type, then153	 * it will handle all reports for sensors in this collection. If154	 * there is also an individual sensor handler registration, then155	 * we want to make sure that the reports are directed to collection156	 * handler, as this may be a fusion sensor. So add collection handlers157	 * to the beginning of the list, so that they are matched first.158	 */159	if (usage_id == HID_USAGE_SENSOR_COLLECTION)160		list_add(&callback->list, &pdata->dyn_callback_list);161	else162		list_add_tail(&callback->list, &pdata->dyn_callback_list);163	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);164 165	return 0;166}167EXPORT_SYMBOL_GPL(sensor_hub_register_callback);168 169int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,170				u32 usage_id)171{172	struct hid_sensor_hub_callbacks_list *callback;173	struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);174	unsigned long flags;175 176	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);177	list_for_each_entry(callback, &pdata->dyn_callback_list, list)178		if (callback->usage_id == usage_id &&179						callback->hsdev == hsdev) {180			list_del(&callback->list);181			kfree(callback);182			break;183		}184	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);185 186	return 0;187}188EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);189 190int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,191			   u32 field_index, int buffer_size, void *buffer)192{193	struct hid_report *report;194	struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);195	__s32 *buf32 = buffer;196	int i = 0;197	int remaining_bytes;198	__s32 value;199	int ret = 0;200 201	mutex_lock(&data->mutex);202	report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);203	if (!report || (field_index >= report->maxfield)) {204		ret = -EINVAL;205		goto done_proc;206	}207 208	remaining_bytes = buffer_size % sizeof(__s32);209	buffer_size = buffer_size / sizeof(__s32);210	if (buffer_size) {211		for (i = 0; i < buffer_size; ++i) {212			ret = hid_set_field(report->field[field_index], i,213					    (__force __s32)cpu_to_le32(*buf32));214			if (ret)215				goto done_proc;216 217			++buf32;218		}219	}220	if (remaining_bytes) {221		value = 0;222		memcpy(&value, (u8 *)buf32, remaining_bytes);223		ret = hid_set_field(report->field[field_index], i,224				    (__force __s32)cpu_to_le32(value));225		if (ret)226			goto done_proc;227	}228	hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT);229	hid_hw_wait(hsdev->hdev);230 231done_proc:232	mutex_unlock(&data->mutex);233 234	return ret;235}236EXPORT_SYMBOL_GPL(sensor_hub_set_feature);237 238int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,239			   u32 field_index, int buffer_size, void *buffer)240{241	struct hid_report *report;242	struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);243	int report_size;244	int ret = 0;245	u8 *val_ptr;246	int buffer_index = 0;247	int i;248 249	memset(buffer, 0, buffer_size);250 251	mutex_lock(&data->mutex);252	report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);253	if (!report || (field_index >= report->maxfield) ||254	    report->field[field_index]->report_count < 1) {255		ret = -EINVAL;256		goto done_proc;257	}258	hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);259	hid_hw_wait(hsdev->hdev);260 261	/* calculate number of bytes required to read this field */262	report_size = DIV_ROUND_UP(report->field[field_index]->report_size,263				   8) *264				   report->field[field_index]->report_count;265	if (!report_size) {266		ret = -EINVAL;267		goto done_proc;268	}269	ret = min(report_size, buffer_size);270 271	val_ptr = (u8 *)report->field[field_index]->value;272	for (i = 0; i < report->field[field_index]->report_count; ++i) {273		if (buffer_index >= ret)274			break;275 276		memcpy(&((u8 *)buffer)[buffer_index], val_ptr,277		       report->field[field_index]->report_size / 8);278		val_ptr += sizeof(__s32);279		buffer_index += (report->field[field_index]->report_size / 8);280	}281 282done_proc:283	mutex_unlock(&data->mutex);284 285	return ret;286}287EXPORT_SYMBOL_GPL(sensor_hub_get_feature);288 289 290int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,291					u32 usage_id,292					u32 attr_usage_id, u32 report_id,293					enum sensor_hub_read_flags flag,294					bool is_signed)295{296	struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);297	unsigned long flags;298	struct hid_report *report;299	int ret_val = 0;300 301	report = sensor_hub_report(report_id, hsdev->hdev,302				   HID_INPUT_REPORT);303	if (!report)304		return -EINVAL;305 306	mutex_lock(hsdev->mutex_ptr);307	if (flag == SENSOR_HUB_SYNC) {308		memset(&hsdev->pending, 0, sizeof(hsdev->pending));309		init_completion(&hsdev->pending.ready);310		hsdev->pending.usage_id = usage_id;311		hsdev->pending.attr_usage_id = attr_usage_id;312		hsdev->pending.raw_size = 0;313 314		spin_lock_irqsave(&data->lock, flags);315		hsdev->pending.status = true;316		spin_unlock_irqrestore(&data->lock, flags);317	}318	mutex_lock(&data->mutex);319	hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);320	mutex_unlock(&data->mutex);321	if (flag == SENSOR_HUB_SYNC) {322		wait_for_completion_interruptible_timeout(323						&hsdev->pending.ready, HZ*5);324		switch (hsdev->pending.raw_size) {325		case 1:326			if (is_signed)327				ret_val = *(s8 *)hsdev->pending.raw_data;328			else329				ret_val = *(u8 *)hsdev->pending.raw_data;330			break;331		case 2:332			if (is_signed)333				ret_val = *(s16 *)hsdev->pending.raw_data;334			else335				ret_val = *(u16 *)hsdev->pending.raw_data;336			break;337		case 4:338			ret_val = *(u32 *)hsdev->pending.raw_data;339			break;340		default:341			ret_val = 0;342		}343		kfree(hsdev->pending.raw_data);344		hsdev->pending.status = false;345	}346	mutex_unlock(hsdev->mutex_ptr);347 348	return ret_val;349}350EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value);351 352int hid_sensor_get_usage_index(struct hid_sensor_hub_device *hsdev,353				u32 report_id, int field_index, u32 usage_id)354{355	struct hid_report *report;356	struct hid_field *field;357	int i;358 359	report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);360	if (!report || (field_index >= report->maxfield))361		goto done_proc;362 363	field = report->field[field_index];364	for (i = 0; i < field->maxusage; ++i) {365		if (field->usage[i].hid == usage_id)366			return field->usage[i].usage_index;367	}368 369done_proc:370	return -EINVAL;371}372EXPORT_SYMBOL_GPL(hid_sensor_get_usage_index);373 374int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,375				u8 type,376				u32 usage_id,377				u32 attr_usage_id,378				struct hid_sensor_hub_attribute_info *info)379{380	int ret = -1;381	int i;382	struct hid_report *report;383	struct hid_field *field;384	struct hid_report_enum *report_enum;385	struct hid_device *hdev = hsdev->hdev;386 387	/* Initialize with defaults */388	info->usage_id = usage_id;389	info->attrib_id = attr_usage_id;390	info->report_id = -1;391	info->index = -1;392	info->units = -1;393	info->unit_expo = -1;394 395	report_enum = &hdev->report_enum[type];396	list_for_each_entry(report, &report_enum->report_list, list) {397		for (i = 0; i < report->maxfield; ++i) {398			field = report->field[i];399			if (field->maxusage) {400				if ((field->physical == usage_id ||401				     field->application == usage_id) &&402					(field->logical == attr_usage_id ||403					field->usage[0].hid ==404							attr_usage_id) &&405					(field->usage[0].collection_index >=406					hsdev->start_collection_index) &&407					(field->usage[0].collection_index <408					hsdev->end_collection_index)) {409 410					sensor_hub_fill_attr_info(info, i,411								report->id,412								field);413					ret = 0;414					break;415				}416			}417		}418 419	}420 421	return ret;422}423EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);424 425#ifdef CONFIG_PM426static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)427{428	struct sensor_hub_data *pdata = hid_get_drvdata(hdev);429	struct hid_sensor_hub_callbacks_list *callback;430	unsigned long flags;431 432	hid_dbg(hdev, " sensor_hub_suspend\n");433	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);434	list_for_each_entry(callback, &pdata->dyn_callback_list, list) {435		if (callback->usage_callback->suspend)436			callback->usage_callback->suspend(437					callback->hsdev, callback->priv);438	}439	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);440 441	return 0;442}443 444static int sensor_hub_resume(struct hid_device *hdev)445{446	struct sensor_hub_data *pdata = hid_get_drvdata(hdev);447	struct hid_sensor_hub_callbacks_list *callback;448	unsigned long flags;449 450	hid_dbg(hdev, " sensor_hub_resume\n");451	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);452	list_for_each_entry(callback, &pdata->dyn_callback_list, list) {453		if (callback->usage_callback->resume)454			callback->usage_callback->resume(455					callback->hsdev, callback->priv);456	}457	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);458 459	return 0;460}461 462static int sensor_hub_reset_resume(struct hid_device *hdev)463{464	return 0;465}466#endif467 468/*469 * Handle raw report as sent by device470 */471static int sensor_hub_raw_event(struct hid_device *hdev,472		struct hid_report *report, u8 *raw_data, int size)473{474	int i;475	u8 *ptr;476	int sz;477	struct sensor_hub_data *pdata = hid_get_drvdata(hdev);478	unsigned long flags;479	struct hid_sensor_hub_callbacks *callback = NULL;480	struct hid_collection *collection = NULL;481	void *priv = NULL;482	struct hid_sensor_hub_device *hsdev = NULL;483 484	hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",485			 report->id, size, report->type);486	hid_dbg(hdev, "maxfield:%d\n", report->maxfield);487	if (report->type != HID_INPUT_REPORT)488		return 1;489 490	ptr = raw_data;491	if (report->id)492		ptr++; /* Skip report id */493 494	spin_lock_irqsave(&pdata->lock, flags);495 496	for (i = 0; i < report->maxfield; ++i) {497		hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",498				i, report->field[i]->usage->collection_index,499				report->field[i]->usage->hid,500				(report->field[i]->report_size *501					report->field[i]->report_count)/8);502		sz = (report->field[i]->report_size *503					report->field[i]->report_count)/8;504		collection = &hdev->collection[505				report->field[i]->usage->collection_index];506		hid_dbg(hdev, "collection->usage %x\n",507					collection->usage);508 509		callback = sensor_hub_get_callback(hdev,510				report->field[i]->physical ? report->field[i]->physical :511							     report->field[i]->application,512				report->field[i]->usage[0].collection_index,513				&hsdev, &priv);514		if (!callback) {515			ptr += sz;516			continue;517		}518		if (hsdev->pending.status && (hsdev->pending.attr_usage_id ==519					      report->field[i]->usage->hid ||520					      hsdev->pending.attr_usage_id ==521					      report->field[i]->logical)) {522			hid_dbg(hdev, "data was pending ...\n");523			hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);524			if (hsdev->pending.raw_data)525				hsdev->pending.raw_size = sz;526			else527				hsdev->pending.raw_size = 0;528			complete(&hsdev->pending.ready);529		}530		if (callback->capture_sample) {531			if (report->field[i]->logical)532				callback->capture_sample(hsdev,533					report->field[i]->logical, sz, ptr,534					callback->pdev);535			else536				callback->capture_sample(hsdev,537					report->field[i]->usage->hid, sz, ptr,538					callback->pdev);539		}540		ptr += sz;541	}542	if (callback && collection && callback->send_event)543		callback->send_event(hsdev, collection->usage,544				callback->pdev);545	spin_unlock_irqrestore(&pdata->lock, flags);546 547	return 1;548}549 550int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)551{552	int ret = 0;553	struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);554 555	mutex_lock(&data->mutex);556	if (!data->ref_cnt) {557		ret = hid_hw_open(hsdev->hdev);558		if (ret) {559			hid_err(hsdev->hdev, "failed to open hid device\n");560			mutex_unlock(&data->mutex);561			return ret;562		}563	}564	data->ref_cnt++;565	mutex_unlock(&data->mutex);566 567	return ret;568}569EXPORT_SYMBOL_GPL(sensor_hub_device_open);570 571void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)572{573	struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);574 575	mutex_lock(&data->mutex);576	data->ref_cnt--;577	if (!data->ref_cnt)578		hid_hw_close(hsdev->hdev);579	mutex_unlock(&data->mutex);580}581EXPORT_SYMBOL_GPL(sensor_hub_device_close);582 583static const __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,584		unsigned int *rsize)585{586	/*587	 * Checks if the report descriptor of Thinkpad Helix 2 has a logical588	 * minimum for magnetic flux axis greater than the maximum.589	 */590	if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&591		*rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&592		rdesc[915] == 0x81 && rdesc[916] == 0x08 &&593		rdesc[917] == 0x00 && rdesc[918] == 0x27 &&594		rdesc[921] == 0x07 && rdesc[922] == 0x00) {595		/* Sets negative logical minimum for mag x, y and z */596		rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;597		rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;598		rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;599		rdesc[917] = rdesc[938] = rdesc[959] = 0xff;600	}601 602	return rdesc;603}604 605static int sensor_hub_probe(struct hid_device *hdev,606				const struct hid_device_id *id)607{608	int ret;609	struct sensor_hub_data *sd;610	int i;611	char *name;612	int dev_cnt;613	struct hid_sensor_hub_device *hsdev;614	struct hid_sensor_hub_device *last_hsdev = NULL;615	struct hid_sensor_hub_device *collection_hsdev = NULL;616 617	sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);618	if (!sd) {619		hid_err(hdev, "cannot allocate Sensor data\n");620		return -ENOMEM;621	}622 623	hid_set_drvdata(hdev, sd);624 625	spin_lock_init(&sd->lock);626	spin_lock_init(&sd->dyn_callback_lock);627	mutex_init(&sd->mutex);628	ret = hid_parse(hdev);629	if (ret) {630		hid_err(hdev, "parse failed\n");631		return ret;632	}633	INIT_LIST_HEAD(&hdev->inputs);634 635	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_DRIVER);636	if (ret) {637		hid_err(hdev, "hw start failed\n");638		return ret;639	}640	INIT_LIST_HEAD(&sd->dyn_callback_list);641	sd->hid_sensor_client_cnt = 0;642 643	dev_cnt = sensor_hub_get_physical_device_count(hdev);644	if (dev_cnt > HID_MAX_PHY_DEVICES) {645		hid_err(hdev, "Invalid Physical device count\n");646		ret = -EINVAL;647		goto err_stop_hw;648	}649	sd->hid_sensor_hub_client_devs = devm_kcalloc(&hdev->dev,650						      dev_cnt,651						      sizeof(struct mfd_cell),652						      GFP_KERNEL);653	if (sd->hid_sensor_hub_client_devs == NULL) {654		hid_err(hdev, "Failed to allocate memory for mfd cells\n");655		ret = -ENOMEM;656		goto err_stop_hw;657	}658 659	for (i = 0; i < hdev->maxcollection; ++i) {660		struct hid_collection *collection = &hdev->collection[i];661 662		if (collection->type == HID_COLLECTION_PHYSICAL ||663		    collection->type == HID_COLLECTION_APPLICATION) {664 665			hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),666					     GFP_KERNEL);667			if (!hsdev) {668				hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");669				ret = -ENOMEM;670				goto err_stop_hw;671			}672			hsdev->hdev = hdev;673			hsdev->vendor_id = hdev->vendor;674			hsdev->product_id = hdev->product;675			hsdev->usage = collection->usage;676			hsdev->mutex_ptr = devm_kzalloc(&hdev->dev,677							sizeof(struct mutex),678							GFP_KERNEL);679			if (!hsdev->mutex_ptr) {680				ret = -ENOMEM;681				goto err_stop_hw;682			}683			mutex_init(hsdev->mutex_ptr);684			hsdev->start_collection_index = i;685			if (last_hsdev)686				last_hsdev->end_collection_index = i;687			last_hsdev = hsdev;688			name = devm_kasprintf(&hdev->dev, GFP_KERNEL,689					      "HID-SENSOR-%x",690					      collection->usage);691			if (name == NULL) {692				hid_err(hdev, "Failed MFD device name\n");693				ret = -ENOMEM;694				goto err_stop_hw;695			}696			sd->hid_sensor_hub_client_devs[697				sd->hid_sensor_client_cnt].name = name;698			sd->hid_sensor_hub_client_devs[699				sd->hid_sensor_client_cnt].platform_data =700							hsdev;701			sd->hid_sensor_hub_client_devs[702				sd->hid_sensor_client_cnt].pdata_size =703							sizeof(*hsdev);704			hid_dbg(hdev, "Adding %s:%d\n", name,705					hsdev->start_collection_index);706			sd->hid_sensor_client_cnt++;707			if (collection_hsdev)708				collection_hsdev->end_collection_index = i;709			if (collection->type == HID_COLLECTION_APPLICATION &&710			    collection->usage == HID_USAGE_SENSOR_COLLECTION)711				collection_hsdev = hsdev;712		}713	}714	if (last_hsdev)715		last_hsdev->end_collection_index = i;716	if (collection_hsdev)717		collection_hsdev->end_collection_index = i;718 719	ret = mfd_add_hotplug_devices(&hdev->dev,720			sd->hid_sensor_hub_client_devs,721			sd->hid_sensor_client_cnt);722	if (ret < 0)723		goto err_stop_hw;724 725	return ret;726 727err_stop_hw:728	hid_hw_stop(hdev);729 730	return ret;731}732 733static void sensor_hub_remove(struct hid_device *hdev)734{735	struct sensor_hub_data *data = hid_get_drvdata(hdev);736	unsigned long flags;737	int i;738 739	hid_dbg(hdev, " hardware removed\n");740	hid_hw_close(hdev);741	hid_hw_stop(hdev);742	spin_lock_irqsave(&data->lock, flags);743	for (i = 0; i < data->hid_sensor_client_cnt; ++i) {744		struct hid_sensor_hub_device *hsdev =745			data->hid_sensor_hub_client_devs[i].platform_data;746		if (hsdev->pending.status)747			complete(&hsdev->pending.ready);748	}749	spin_unlock_irqrestore(&data->lock, flags);750	mfd_remove_devices(&hdev->dev);751	mutex_destroy(&data->mutex);752}753 754static const struct hid_device_id sensor_hub_devices[] = {755	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,756		     HID_ANY_ID) },757	{ }758};759MODULE_DEVICE_TABLE(hid, sensor_hub_devices);760 761static struct hid_driver sensor_hub_driver = {762	.name = "hid-sensor-hub",763	.id_table = sensor_hub_devices,764	.probe = sensor_hub_probe,765	.remove = sensor_hub_remove,766	.raw_event = sensor_hub_raw_event,767	.report_fixup = sensor_hub_report_fixup,768#ifdef CONFIG_PM769	.suspend = sensor_hub_suspend,770	.resume = sensor_hub_resume,771	.reset_resume = sensor_hub_reset_resume,772#endif773};774module_hid_driver(sensor_hub_driver);775 776MODULE_DESCRIPTION("HID Sensor Hub driver");777MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");778MODULE_LICENSE("GPL");779