blob: 5e0f14369145dcc291c6e2600a18bf1c0aea029e [file] [log] [blame]
Roland Stigge8b7c3b62012-04-29 16:47:04 +02001/*
2 * NXP ISP1301 USB transceiver driver
3 *
4 * Copyright (C) 2012 Roland Stigge
5 *
6 * Author: Roland Stigge <stigge@antcom.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
Felipe Balbi790d3a52013-03-08 13:01:40 +020014#include <linux/mutex.h>
Roland Stigge8b7c3b62012-04-29 16:47:04 +020015#include <linux/i2c.h>
Felipe Balbi790d3a52013-03-08 13:01:40 +020016#include <linux/usb/phy.h>
Roland Stigge8b7c3b62012-04-29 16:47:04 +020017
18#define DRV_NAME "isp1301"
19
Felipe Balbi790d3a52013-03-08 13:01:40 +020020struct isp1301 {
21 struct usb_phy phy;
22 struct mutex mutex;
23
24 struct i2c_client *client;
25};
26
Roland Stigge8b7c3b62012-04-29 16:47:04 +020027static const struct i2c_device_id isp1301_id[] = {
28 { "isp1301", 0 },
29 { }
30};
31
32static struct i2c_client *isp1301_i2c_client;
33
34static int isp1301_probe(struct i2c_client *client,
35 const struct i2c_device_id *i2c_id)
36{
Felipe Balbi790d3a52013-03-08 13:01:40 +020037 struct isp1301 *isp;
38 struct usb_phy *phy;
39
40 isp = devm_kzalloc(&client->dev, sizeof(*isp), GFP_KERNEL);
41 if (!isp)
42 return -ENOMEM;
43
44 isp->client = client;
45 mutex_init(&isp->mutex);
46
47 phy = &isp->phy;
48 phy->label = DRV_NAME;
49 phy->type = USB_PHY_TYPE_USB2;
50
51 i2c_set_clientdata(client, isp);
52 usb_add_phy_dev(phy);
53
Roland Stigge8b7c3b62012-04-29 16:47:04 +020054 isp1301_i2c_client = client;
Felipe Balbi790d3a52013-03-08 13:01:40 +020055
Roland Stigge8b7c3b62012-04-29 16:47:04 +020056 return 0;
57}
58
59static int isp1301_remove(struct i2c_client *client)
60{
Felipe Balbi790d3a52013-03-08 13:01:40 +020061 struct isp1301 *isp = i2c_get_clientdata(client);
62
63 usb_remove_phy(&isp->phy);
64 isp1301_i2c_client = NULL;
65
Roland Stigge8b7c3b62012-04-29 16:47:04 +020066 return 0;
67}
68
69static struct i2c_driver isp1301_driver = {
70 .driver = {
71 .name = DRV_NAME,
72 },
73 .probe = isp1301_probe,
74 .remove = isp1301_remove,
75 .id_table = isp1301_id,
76};
77
78module_i2c_driver(isp1301_driver);
79
80static int match(struct device *dev, void *data)
81{
82 struct device_node *node = (struct device_node *)data;
83 return (dev->of_node == node) &&
84 (dev->driver == &isp1301_driver.driver);
85}
86
87struct i2c_client *isp1301_get_client(struct device_node *node)
88{
89 if (node) { /* reference of ISP1301 I2C node via DT */
90 struct device *dev = bus_find_device(&i2c_bus_type, NULL,
91 node, match);
92 if (!dev)
93 return NULL;
94 return to_i2c_client(dev);
95 } else { /* non-DT: only one ISP1301 chip supported */
96 return isp1301_i2c_client;
97 }
98}
99EXPORT_SYMBOL_GPL(isp1301_get_client);
100
101MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
102MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver");
103MODULE_LICENSE("GPL");