aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/iuu_phoenix.c
diff options
context:
space:
mode:
authorOlivier Bornet <Olivier.Bornet@puck.ch>2009-08-18 15:05:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:35 -0400
commit20eda943cc55b2bfdb6b6e4a3da23c8f198910c8 (patch)
treeee73bea7000afb028fa8f3834af761209551fedc /drivers/usb/serial/iuu_phoenix.c
parent8844a32d54988ddf9eaf8f439085491547debcc8 (diff)
USB: iuu_phoenix: add support for changing VCC
You can now set the IUU reader to 3.3V VCC instead of 5V VCC, using the sysfs parameter vcc_mode. Valid values are 3 and 5. Signed-off-by: Olivier Bornet <Olivier.Bornet@puck.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/iuu_phoenix.c')
-rw-r--r--drivers/usb/serial/iuu_phoenix.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 60a7d8dc0758..5f133429cd45 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -79,6 +79,7 @@ struct iuu_private {
79 u8 *buf; /* used for initialize speed */ 79 u8 *buf; /* used for initialize speed */
80 u8 *dbgbuf; /* debug buffer */ 80 u8 *dbgbuf; /* debug buffer */
81 u8 len; 81 u8 len;
82 int vcc; /* vcc (either 3 or 5 V) */
82}; 83};
83 84
84 85
@@ -114,6 +115,7 @@ static int iuu_startup(struct usb_serial *serial)
114 kfree(priv); 115 kfree(priv);
115 return -ENOMEM; 116 return -ENOMEM;
116 } 117 }
118 priv->vcc = 5; /* 5 V for vcc by default */
117 spin_lock_init(&priv->lock); 119 spin_lock_init(&priv->lock);
118 init_waitqueue_head(&priv->delta_msr_wait); 120 init_waitqueue_head(&priv->delta_msr_wait);
119 usb_set_serial_port_data(serial->port[0], priv); 121 usb_set_serial_port_data(serial->port[0], priv);
@@ -1178,6 +1180,95 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
1178 return result; 1180 return result;
1179} 1181}
1180 1182
1183/* how to change VCC */
1184static int iuu_vcc_set(struct usb_serial_port *port, unsigned int vcc)
1185{
1186 int status;
1187 u8 *buf;
1188
1189 buf = kmalloc(5, GFP_KERNEL);
1190 if (!buf)
1191 return -ENOMEM;
1192
1193 dbg("%s - enter", __func__);
1194
1195 buf[0] = IUU_SET_VCC;
1196 buf[1] = vcc & 0xFF;
1197 buf[2] = (vcc >> 8) & 0xFF;
1198 buf[3] = (vcc >> 16) & 0xFF;
1199 buf[4] = (vcc >> 24) & 0xFF;
1200
1201 status = bulk_immediate(port, buf, 5);
1202 kfree(buf);
1203
1204 if (status != IUU_OPERATION_OK)
1205 dbg("%s - vcc error status = %2x", __func__, status);
1206 else
1207 dbg("%s - vcc OK !", __func__);
1208
1209 return status;
1210}
1211
1212/*
1213 * Sysfs Attributes
1214 */
1215
1216static ssize_t show_vcc_mode(struct device *dev,
1217 struct device_attribute *attr, char *buf)
1218{
1219 struct usb_serial_port *port = to_usb_serial_port(dev);
1220 struct iuu_private *priv = usb_get_serial_port_data(port);
1221
1222 return sprintf(buf, "%d\n", priv->vcc);
1223}
1224
1225static ssize_t store_vcc_mode(struct device *dev,
1226 struct device_attribute *attr, const char *buf, size_t count)
1227{
1228 struct usb_serial_port *port = to_usb_serial_port(dev);
1229 struct iuu_private *priv = usb_get_serial_port_data(port);
1230 unsigned long v;
1231
1232 if (strict_strtoul(buf, 10, &v)) {
1233 dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n",
1234 __func__, buf);
1235 goto fail_store_vcc_mode;
1236 }
1237
1238 dbg("%s: setting vcc_mode = %ld", __func__, v);
1239
1240 if ((v != 3) && (v != 5)) {
1241 dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v);
1242 } else {
1243 iuu_vcc_set(port, v);
1244 priv->vcc = v;
1245 }
1246fail_store_vcc_mode:
1247 return count;
1248}
1249
1250static DEVICE_ATTR(vcc_mode, S_IRUSR | S_IWUSR, show_vcc_mode,
1251 store_vcc_mode);
1252
1253static int iuu_create_sysfs_attrs(struct usb_serial_port *port)
1254{
1255 dbg("%s", __func__);
1256
1257 return device_create_file(&port->dev, &dev_attr_vcc_mode);
1258}
1259
1260static int iuu_remove_sysfs_attrs(struct usb_serial_port *port)
1261{
1262 dbg("%s", __func__);
1263
1264 device_remove_file(&port->dev, &dev_attr_vcc_mode);
1265 return 0;
1266}
1267
1268/*
1269 * End Sysfs Attributes
1270 */
1271
1181static struct usb_serial_driver iuu_device = { 1272static struct usb_serial_driver iuu_device = {
1182 .driver = { 1273 .driver = {
1183 .owner = THIS_MODULE, 1274 .owner = THIS_MODULE,
@@ -1185,6 +1276,8 @@ static struct usb_serial_driver iuu_device = {
1185 }, 1276 },
1186 .id_table = id_table, 1277 .id_table = id_table,
1187 .num_ports = 1, 1278 .num_ports = 1,
1279 .port_probe = iuu_create_sysfs_attrs,
1280 .port_remove = iuu_remove_sysfs_attrs,
1188 .open = iuu_open, 1281 .open = iuu_open,
1189 .close = iuu_close, 1282 .close = iuu_close,
1190 .write = iuu_uart_write, 1283 .write = iuu_uart_write,