aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/iuu_phoenix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/iuu_phoenix.c')
-rw-r--r--drivers/usb/serial/iuu_phoenix.c115
1 files changed, 105 insertions, 10 deletions
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 6138c1cda35f..e6e02b178d2b 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -40,7 +40,7 @@ static int debug;
40/* 40/*
41 * Version Information 41 * Version Information
42 */ 42 */
43#define DRIVER_VERSION "v0.10" 43#define DRIVER_VERSION "v0.11"
44#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" 44#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
45 45
46static struct usb_device_id id_table[] = { 46static struct usb_device_id id_table[] = {
@@ -64,6 +64,7 @@ static int cdmode = 1;
64static int iuu_cardin; 64static int iuu_cardin;
65static int iuu_cardout; 65static int iuu_cardout;
66static int xmas; 66static int xmas;
67static int vcc_default = 5;
67 68
68static void read_rxcmd_callback(struct urb *urb); 69static void read_rxcmd_callback(struct urb *urb);
69 70
@@ -79,6 +80,7 @@ struct iuu_private {
79 u8 *buf; /* used for initialize speed */ 80 u8 *buf; /* used for initialize speed */
80 u8 *dbgbuf; /* debug buffer */ 81 u8 *dbgbuf; /* debug buffer */
81 u8 len; 82 u8 len;
83 int vcc; /* vcc (either 3 or 5 V) */
82}; 84};
83 85
84 86
@@ -114,6 +116,7 @@ static int iuu_startup(struct usb_serial *serial)
114 kfree(priv); 116 kfree(priv);
115 return -ENOMEM; 117 return -ENOMEM;
116 } 118 }
119 priv->vcc = vcc_default;
117 spin_lock_init(&priv->lock); 120 spin_lock_init(&priv->lock);
118 init_waitqueue_head(&priv->delta_msr_wait); 121 init_waitqueue_head(&priv->delta_msr_wait);
119 usb_set_serial_port_data(serial->port[0], priv); 122 usb_set_serial_port_data(serial->port[0], priv);
@@ -1009,11 +1012,7 @@ static void iuu_close(struct usb_serial_port *port)
1009 usb_kill_urb(port->write_urb); 1012 usb_kill_urb(port->write_urb);
1010 usb_kill_urb(port->read_urb); 1013 usb_kill_urb(port->read_urb);
1011 usb_kill_urb(port->interrupt_in_urb); 1014 usb_kill_urb(port->interrupt_in_urb);
1012 msleep(1000);
1013 /* wait one second to free all buffers */
1014 iuu_led(port, 0, 0, 0xF000, 0xFF); 1015 iuu_led(port, 0, 0, 0xF000, 0xFF);
1015 msleep(1000);
1016 usb_reset_device(port->serial->dev);
1017 } 1016 }
1018} 1017}
1019 1018
@@ -1182,6 +1181,95 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
1182 return result; 1181 return result;
1183} 1182}
1184 1183
1184/* how to change VCC */
1185static int iuu_vcc_set(struct usb_serial_port *port, unsigned int vcc)
1186{
1187 int status;
1188 u8 *buf;
1189
1190 buf = kmalloc(5, GFP_KERNEL);
1191 if (!buf)
1192 return -ENOMEM;
1193
1194 dbg("%s - enter", __func__);
1195
1196 buf[0] = IUU_SET_VCC;
1197 buf[1] = vcc & 0xFF;
1198 buf[2] = (vcc >> 8) & 0xFF;
1199 buf[3] = (vcc >> 16) & 0xFF;
1200 buf[4] = (vcc >> 24) & 0xFF;
1201
1202 status = bulk_immediate(port, buf, 5);
1203 kfree(buf);
1204
1205 if (status != IUU_OPERATION_OK)
1206 dbg("%s - vcc error status = %2x", __func__, status);
1207 else
1208 dbg("%s - vcc OK !", __func__);
1209
1210 return status;
1211}
1212
1213/*
1214 * Sysfs Attributes
1215 */
1216
1217static ssize_t show_vcc_mode(struct device *dev,
1218 struct device_attribute *attr, char *buf)
1219{
1220 struct usb_serial_port *port = to_usb_serial_port(dev);
1221 struct iuu_private *priv = usb_get_serial_port_data(port);
1222
1223 return sprintf(buf, "%d\n", priv->vcc);
1224}
1225
1226static ssize_t store_vcc_mode(struct device *dev,
1227 struct device_attribute *attr, const char *buf, size_t count)
1228{
1229 struct usb_serial_port *port = to_usb_serial_port(dev);
1230 struct iuu_private *priv = usb_get_serial_port_data(port);
1231 unsigned long v;
1232
1233 if (strict_strtoul(buf, 10, &v)) {
1234 dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n",
1235 __func__, buf);
1236 goto fail_store_vcc_mode;
1237 }
1238
1239 dbg("%s: setting vcc_mode = %ld", __func__, v);
1240
1241 if ((v != 3) && (v != 5)) {
1242 dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v);
1243 } else {
1244 iuu_vcc_set(port, v);
1245 priv->vcc = v;
1246 }
1247fail_store_vcc_mode:
1248 return count;
1249}
1250
1251static DEVICE_ATTR(vcc_mode, S_IRUSR | S_IWUSR, show_vcc_mode,
1252 store_vcc_mode);
1253
1254static int iuu_create_sysfs_attrs(struct usb_serial_port *port)
1255{
1256 dbg("%s", __func__);
1257
1258 return device_create_file(&port->dev, &dev_attr_vcc_mode);
1259}
1260
1261static int iuu_remove_sysfs_attrs(struct usb_serial_port *port)
1262{
1263 dbg("%s", __func__);
1264
1265 device_remove_file(&port->dev, &dev_attr_vcc_mode);
1266 return 0;
1267}
1268
1269/*
1270 * End Sysfs Attributes
1271 */
1272
1185static struct usb_serial_driver iuu_device = { 1273static struct usb_serial_driver iuu_device = {
1186 .driver = { 1274 .driver = {
1187 .owner = THIS_MODULE, 1275 .owner = THIS_MODULE,
@@ -1189,6 +1277,8 @@ static struct usb_serial_driver iuu_device = {
1189 }, 1277 },
1190 .id_table = id_table, 1278 .id_table = id_table,
1191 .num_ports = 1, 1279 .num_ports = 1,
1280 .port_probe = iuu_create_sysfs_attrs,
1281 .port_remove = iuu_remove_sysfs_attrs,
1192 .open = iuu_open, 1282 .open = iuu_open,
1193 .close = iuu_close, 1283 .close = iuu_close,
1194 .write = iuu_uart_write, 1284 .write = iuu_uart_write,
@@ -1238,14 +1328,19 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
1238MODULE_PARM_DESC(debug, "Debug enabled or not"); 1328MODULE_PARM_DESC(debug, "Debug enabled or not");
1239 1329
1240module_param(xmas, bool, S_IRUGO | S_IWUSR); 1330module_param(xmas, bool, S_IRUGO | S_IWUSR);
1241MODULE_PARM_DESC(xmas, "xmas color enabled or not"); 1331MODULE_PARM_DESC(xmas, "Xmas colors enabled or not");
1242 1332
1243module_param(boost, int, S_IRUGO | S_IWUSR); 1333module_param(boost, int, S_IRUGO | S_IWUSR);
1244MODULE_PARM_DESC(boost, "overclock boost percent 100 to 500"); 1334MODULE_PARM_DESC(boost, "Card overclock boost (in percent 100-500)");
1245 1335
1246module_param(clockmode, int, S_IRUGO | S_IWUSR); 1336module_param(clockmode, int, S_IRUGO | S_IWUSR);
1247MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz"); 1337MODULE_PARM_DESC(clockmode, "Card clock mode (1=3.579 MHz, 2=3.680 MHz, "
1338 "3=6 Mhz)");
1248 1339
1249module_param(cdmode, int, S_IRUGO | S_IWUSR); 1340module_param(cdmode, int, S_IRUGO | S_IWUSR);
1250MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, " 1341MODULE_PARM_DESC(cdmode, "Card detect mode (0=none, 1=CD, 2=!CD, 3=DSR, "
1251 "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING"); 1342 "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING)");
1343
1344module_param(vcc_default, int, S_IRUGO | S_IWUSR);
1345MODULE_PARM_DESC(vcc_default, "Set default VCC (either 3 for 3.3V or 5 "
1346 "for 5V). Default to 5.");