aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/mos7840.c349
1 files changed, 166 insertions, 183 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index bc3df86134fe..1cf3375ec1af 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -2340,208 +2340,191 @@ static int mos7840_port_probe(struct usb_serial_port *port)
2340 2340
2341 pnum = port->number - serial->minor; 2341 pnum = port->number - serial->minor;
2342 2342
2343 /* FIXME: remove do-while(0) loop used to keep stable patch minimal. 2343 dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum);
2344 */ 2344 mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
2345 do { 2345 if (mos7840_port == NULL) {
2346 dev_dbg(&port->dev, "mos7840_startup: configuring port %d............\n", pnum); 2346 dev_err(&port->dev, "%s - Out of memory\n", __func__);
2347 mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); 2347 return -ENOMEM;
2348 if (mos7840_port == NULL) { 2348 }
2349 dev_err(&port->dev, "%s - Out of memory\n", __func__);
2350 return -ENOMEM;
2351 }
2352
2353 /* Initialize all port interrupt end point to port 0 int
2354 * endpoint. Our device has only one interrupt end point
2355 * common to all port */
2356
2357 mos7840_port->port = port;
2358 mos7840_set_port_private(port, mos7840_port);
2359 spin_lock_init(&mos7840_port->pool_lock);
2360
2361 /* minor is not initialised until later by
2362 * usb-serial.c:get_free_serial() and cannot therefore be used
2363 * to index device instances */
2364 mos7840_port->port_num = pnum + 1;
2365 dev_dbg(&port->dev, "port->number = %d\n", port->number);
2366 dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor);
2367 dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
2368 dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor);
2369
2370 if (mos7840_port->port_num == 1) {
2371 mos7840_port->SpRegOffset = 0x0;
2372 mos7840_port->ControlRegOffset = 0x1;
2373 mos7840_port->DcrRegOffset = 0x4;
2374 } else if ((mos7840_port->port_num == 2)
2375 && (serial->num_ports == 4)) {
2376 mos7840_port->SpRegOffset = 0x8;
2377 mos7840_port->ControlRegOffset = 0x9;
2378 mos7840_port->DcrRegOffset = 0x16;
2379 } else if ((mos7840_port->port_num == 2)
2380 && (serial->num_ports == 2)) {
2381 mos7840_port->SpRegOffset = 0xa;
2382 mos7840_port->ControlRegOffset = 0xb;
2383 mos7840_port->DcrRegOffset = 0x19;
2384 } else if ((mos7840_port->port_num == 3)
2385 && (serial->num_ports == 4)) {
2386 mos7840_port->SpRegOffset = 0xa;
2387 mos7840_port->ControlRegOffset = 0xb;
2388 mos7840_port->DcrRegOffset = 0x19;
2389 } else if ((mos7840_port->port_num == 4)
2390 && (serial->num_ports == 4)) {
2391 mos7840_port->SpRegOffset = 0xc;
2392 mos7840_port->ControlRegOffset = 0xd;
2393 mos7840_port->DcrRegOffset = 0x1c;
2394 }
2395 mos7840_dump_serial_port(port, mos7840_port);
2396 mos7840_set_port_private(port, mos7840_port);
2397 2349
2398 /* enable rx_disable bit in control register */ 2350 /* Initialize all port interrupt end point to port 0 int
2399 status = mos7840_get_reg_sync(port, 2351 * endpoint. Our device has only one interrupt end point
2400 mos7840_port->ControlRegOffset, &Data); 2352 * common to all port */
2401 if (status < 0) { 2353
2402 dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status); 2354 mos7840_port->port = port;
2403 break; 2355 mos7840_set_port_private(port, mos7840_port);
2404 } else 2356 spin_lock_init(&mos7840_port->pool_lock);
2405 dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); 2357
2406 Data |= 0x08; /* setting driver done bit */ 2358 /* minor is not initialised until later by
2407 Data |= 0x04; /* sp1_bit to have cts change reflect in 2359 * usb-serial.c:get_free_serial() and cannot therefore be used
2408 modem status reg */ 2360 * to index device instances */
2361 mos7840_port->port_num = pnum + 1;
2362 dev_dbg(&port->dev, "port->number = %d\n", port->number);
2363 dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor);
2364 dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
2365 dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor);
2366
2367 if (mos7840_port->port_num == 1) {
2368 mos7840_port->SpRegOffset = 0x0;
2369 mos7840_port->ControlRegOffset = 0x1;
2370 mos7840_port->DcrRegOffset = 0x4;
2371 } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) {
2372 mos7840_port->SpRegOffset = 0x8;
2373 mos7840_port->ControlRegOffset = 0x9;
2374 mos7840_port->DcrRegOffset = 0x16;
2375 } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) {
2376 mos7840_port->SpRegOffset = 0xa;
2377 mos7840_port->ControlRegOffset = 0xb;
2378 mos7840_port->DcrRegOffset = 0x19;
2379 } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) {
2380 mos7840_port->SpRegOffset = 0xa;
2381 mos7840_port->ControlRegOffset = 0xb;
2382 mos7840_port->DcrRegOffset = 0x19;
2383 } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) {
2384 mos7840_port->SpRegOffset = 0xc;
2385 mos7840_port->ControlRegOffset = 0xd;
2386 mos7840_port->DcrRegOffset = 0x1c;
2387 }
2388 mos7840_dump_serial_port(port, mos7840_port);
2389 mos7840_set_port_private(port, mos7840_port);
2390
2391 /* enable rx_disable bit in control register */
2392 status = mos7840_get_reg_sync(port,
2393 mos7840_port->ControlRegOffset, &Data);
2394 if (status < 0) {
2395 dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status);
2396 goto out;
2397 } else
2398 dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
2399 Data |= 0x08; /* setting driver done bit */
2400 Data |= 0x04; /* sp1_bit to have cts change reflect in
2401 modem status reg */
2402
2403 /* Data |= 0x20; //rx_disable bit */
2404 status = mos7840_set_reg_sync(port,
2405 mos7840_port->ControlRegOffset, Data);
2406 if (status < 0) {
2407 dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
2408 goto out;
2409 } else
2410 dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
2411
2412 /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
2413 and 0x24 in DCR3 */
2414 Data = 0x01;
2415 status = mos7840_set_reg_sync(port,
2416 (__u16) (mos7840_port->DcrRegOffset + 0), Data);
2417 if (status < 0) {
2418 dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status);
2419 goto out;
2420 } else
2421 dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status);
2409 2422
2410 /* Data |= 0x20; //rx_disable bit */ 2423 Data = 0x05;
2411 status = mos7840_set_reg_sync(port, 2424 status = mos7840_set_reg_sync(port,
2412 mos7840_port->ControlRegOffset, Data); 2425 (__u16) (mos7840_port->DcrRegOffset + 1), Data);
2413 if (status < 0) { 2426 if (status < 0) {
2414 dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); 2427 dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status);
2415 break; 2428 goto out;
2416 } else 2429 } else
2417 dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status); 2430 dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status);
2418 2431
2419 /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 2432 Data = 0x24;
2420 and 0x24 in DCR3 */ 2433 status = mos7840_set_reg_sync(port,
2421 Data = 0x01; 2434 (__u16) (mos7840_port->DcrRegOffset + 2), Data);
2422 status = mos7840_set_reg_sync(port, 2435 if (status < 0) {
2423 (__u16) (mos7840_port->DcrRegOffset + 0), Data); 2436 dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status);
2424 if (status < 0) { 2437 goto out;
2425 dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status); 2438 } else
2426 break; 2439 dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status);
2427 } else
2428 dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status);
2429 2440
2430 Data = 0x05; 2441 /* write values in clkstart0x0 and clkmulti 0x20 */
2431 status = mos7840_set_reg_sync(port, 2442 Data = 0x0;
2432 (__u16) (mos7840_port->DcrRegOffset + 1), Data); 2443 status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data);
2433 if (status < 0) { 2444 if (status < 0) {
2434 dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status); 2445 dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
2435 break; 2446 goto out;
2436 } else 2447 } else
2437 dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status); 2448 dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
2438 2449
2439 Data = 0x24; 2450 Data = 0x20;
2440 status = mos7840_set_reg_sync(port, 2451 status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data);
2441 (__u16) (mos7840_port->DcrRegOffset + 2), Data); 2452 if (status < 0) {
2442 if (status < 0) { 2453 dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
2443 dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status); 2454 goto error;
2444 break; 2455 } else
2445 } else 2456 dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
2446 dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status);
2447 2457
2448 /* write values in clkstart0x0 and clkmulti 0x20 */ 2458 /* write value 0x0 to scratchpad register */
2449 Data = 0x0; 2459 Data = 0x00;
2460 status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
2461 if (status < 0) {
2462 dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
2463 goto out;
2464 } else
2465 dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
2466
2467 /* Zero Length flag register */
2468 if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) {
2469 Data = 0xff;
2450 status = mos7840_set_reg_sync(port, 2470 status = mos7840_set_reg_sync(port,
2451 CLK_START_VALUE_REGISTER, Data); 2471 (__u16) (ZLP_REG1 +
2472 ((__u16)mos7840_port->port_num)), Data);
2473 dev_dbg(&port->dev, "ZLIP offset %x\n",
2474 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
2452 if (status < 0) { 2475 if (status < 0) {
2453 dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); 2476 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status);
2454 break; 2477 goto out;
2455 } else 2478 } else
2456 dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); 2479 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status);
2457 2480 } else {
2458 Data = 0x20; 2481 Data = 0xff;
2459 status = mos7840_set_reg_sync(port, 2482 status = mos7840_set_reg_sync(port,
2460 CLK_MULTI_REGISTER, Data); 2483 (__u16) (ZLP_REG1 +
2461 if (status < 0) { 2484 ((__u16)mos7840_port->port_num) - 0x1), Data);
2462 dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); 2485 dev_dbg(&port->dev, "ZLIP offset %x\n",
2463 goto error; 2486 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
2464 } else
2465 dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
2466
2467 /* write value 0x0 to scratchpad register */
2468 Data = 0x00;
2469 status = mos7840_set_uart_reg(port,
2470 SCRATCH_PAD_REGISTER, Data);
2471 if (status < 0) { 2487 if (status < 0) {
2472 dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); 2488 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status);
2473 break; 2489 goto out;
2474 } else 2490 } else
2475 dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); 2491 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status);
2476 2492
2477 /* Zero Length flag register */ 2493 }
2478 if ((mos7840_port->port_num != 1) 2494 mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
2479 && (serial->num_ports == 2)) { 2495 mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
2480 2496 mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
2481 Data = 0xff; 2497 GFP_KERNEL);
2482 status = mos7840_set_reg_sync(port, 2498 if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
2483 (__u16) (ZLP_REG1 + 2499 !mos7840_port->dr) {
2484 ((__u16)mos7840_port->port_num)), Data); 2500 status = -ENOMEM;
2485 dev_dbg(&port->dev, "ZLIP offset %x\n", 2501 goto error;
2486 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); 2502 }
2487 if (status < 0) {
2488 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status);
2489 break;
2490 } else
2491 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status);
2492 } else {
2493 Data = 0xff;
2494 status = mos7840_set_reg_sync(port,
2495 (__u16) (ZLP_REG1 +
2496 ((__u16)mos7840_port->port_num) - 0x1), Data);
2497 dev_dbg(&port->dev, "ZLIP offset %x\n",
2498 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
2499 if (status < 0) {
2500 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status);
2501 break;
2502 } else
2503 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status);
2504
2505 }
2506 mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
2507 mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
2508 mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
2509 GFP_KERNEL);
2510 if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
2511 !mos7840_port->dr) {
2512 status = -ENOMEM;
2513 goto error;
2514 }
2515
2516 mos7840_port->has_led = false;
2517 2503
2518 /* Initialize LED timers */ 2504 mos7840_port->has_led = false;
2519 if (device_type == MOSCHIP_DEVICE_ID_7810) {
2520 mos7840_port->has_led = true;
2521 2505
2522 init_timer(&mos7840_port->led_timer1); 2506 /* Initialize LED timers */
2523 mos7840_port->led_timer1.function = mos7840_led_off; 2507 if (device_type == MOSCHIP_DEVICE_ID_7810) {
2524 mos7840_port->led_timer1.expires = 2508 mos7840_port->has_led = true;
2525 jiffies + msecs_to_jiffies(LED_ON_MS);
2526 mos7840_port->led_timer1.data =
2527 (unsigned long)mos7840_port;
2528 2509
2529 init_timer(&mos7840_port->led_timer2); 2510 init_timer(&mos7840_port->led_timer1);
2530 mos7840_port->led_timer2.function = 2511 mos7840_port->led_timer1.function = mos7840_led_off;
2531 mos7840_led_flag_off; 2512 mos7840_port->led_timer1.expires =
2532 mos7840_port->led_timer2.expires = 2513 jiffies + msecs_to_jiffies(LED_ON_MS);
2533 jiffies + msecs_to_jiffies(LED_OFF_MS); 2514 mos7840_port->led_timer1.data = (unsigned long)mos7840_port;
2534 mos7840_port->led_timer2.data =
2535 (unsigned long)mos7840_port;
2536 2515
2537 mos7840_port->led_flag = false; 2516 init_timer(&mos7840_port->led_timer2);
2517 mos7840_port->led_timer2.function = mos7840_led_flag_off;
2518 mos7840_port->led_timer2.expires =
2519 jiffies + msecs_to_jiffies(LED_OFF_MS);
2520 mos7840_port->led_timer2.data = (unsigned long)mos7840_port;
2538 2521
2539 /* Turn off LED */ 2522 mos7840_port->led_flag = false;
2540 mos7840_set_led_sync(port,
2541 MODEM_CONTROL_REGISTER, 0x0300);
2542 }
2543 } while (0);
2544 2523
2524 /* Turn off LED */
2525 mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
2526 }
2527out:
2545 if (pnum == serial->num_ports - 1) { 2528 if (pnum == serial->num_ports - 1) {
2546 /* Zero Length flag enable */ 2529 /* Zero Length flag enable */
2547 Data = 0x0f; 2530 Data = 0x0f;