14
14
#include "intel-thc-hw.h"
15
15
16
16
#include "quickspi-dev.h"
17
+ #include "quickspi-hid.h"
18
+ #include "quickspi-protocol.h"
17
19
18
20
struct quickspi_driver_data mtl = {
19
21
.max_packet_size_value = MAX_PACKET_SIZE_VALUE_MTL ,
@@ -228,6 +230,37 @@ static irqreturn_t quickspi_irq_quick_handler(int irq, void *dev_id)
228
230
return IRQ_WAKE_THREAD ;
229
231
}
230
232
233
+ /**
234
+ * try_recover - Try to recovery THC and Device
235
+ * @qsdev: pointer to quickspi device
236
+ *
237
+ * This function is a error handler, called when fatal error happens.
238
+ * It try to reset Touch Device and re-configure THC to recovery
239
+ * transferring between Device and THC.
240
+ *
241
+ * Return: 0 if successful or error code on failed.
242
+ */
243
+ static int try_recover (struct quickspi_device * qsdev )
244
+ {
245
+ int ret ;
246
+
247
+ ret = reset_tic (qsdev );
248
+ if (ret ) {
249
+ dev_err (qsdev -> dev , "Reset touch device failed, ret = %d\n" , ret );
250
+ return ret ;
251
+ }
252
+
253
+ thc_dma_unconfigure (qsdev -> thc_hw );
254
+
255
+ ret = thc_dma_configure (qsdev -> thc_hw );
256
+ if (ret ) {
257
+ dev_err (qsdev -> dev , "Re-configure THC DMA failed, ret = %d\n" , ret );
258
+ return ret ;
259
+ }
260
+
261
+ return 0 ;
262
+ }
263
+
231
264
/**
232
265
* quickspi_irq_thread_handler - IRQ thread handler of quickspi driver
233
266
*
@@ -239,15 +272,52 @@ static irqreturn_t quickspi_irq_quick_handler(int irq, void *dev_id)
239
272
static irqreturn_t quickspi_irq_thread_handler (int irq , void * dev_id )
240
273
{
241
274
struct quickspi_device * qsdev = dev_id ;
275
+ size_t input_len ;
276
+ int read_finished = 0 ;
277
+ int err_recover = 0 ;
242
278
int int_mask ;
279
+ int ret ;
243
280
244
281
if (qsdev -> state == QUICKSPI_DISABLED )
245
282
return IRQ_HANDLED ;
246
283
247
284
int_mask = thc_interrupt_handler (qsdev -> thc_hw );
248
285
286
+ if (int_mask & BIT (THC_FATAL_ERR_INT ) || int_mask & BIT (THC_TXN_ERR_INT )) {
287
+ err_recover = 1 ;
288
+ goto end ;
289
+ }
290
+
291
+ if (int_mask & BIT (THC_NONDMA_INT )) {
292
+ if (qsdev -> state == QUICKSPI_RESETING ) {
293
+ qsdev -> reset_ack = true;
294
+ wake_up_interruptible (& qsdev -> reset_ack_wq );
295
+ } else {
296
+ qsdev -> nondma_int_received = true;
297
+ wake_up_interruptible (& qsdev -> nondma_int_received_wq );
298
+ }
299
+ }
300
+
301
+ if (int_mask & BIT (THC_RXDMA2_INT )) {
302
+ while (!read_finished ) {
303
+ ret = thc_rxdma_read (qsdev -> thc_hw , THC_RXDMA2 , qsdev -> input_buf ,
304
+ & input_len , & read_finished );
305
+ if (ret ) {
306
+ err_recover = 1 ;
307
+ goto end ;
308
+ }
309
+
310
+ quickspi_handle_input_data (qsdev , input_len );
311
+ }
312
+ }
313
+
314
+ end :
249
315
thc_interrupt_enable (qsdev -> thc_hw , true);
250
316
317
+ if (err_recover )
318
+ if (try_recover (qsdev ))
319
+ qsdev -> state = QUICKSPI_DISABLED ;
320
+
251
321
return IRQ_HANDLED ;
252
322
}
253
323
@@ -280,8 +350,15 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
280
350
qsdev -> pdev = pdev ;
281
351
qsdev -> dev = dev ;
282
352
qsdev -> mem_addr = mem_addr ;
353
+ qsdev -> state = QUICKSPI_DISABLED ;
283
354
qsdev -> driver_data = (struct quickspi_driver_data * )id -> driver_data ;
284
355
356
+ init_waitqueue_head (& qsdev -> reset_ack_wq );
357
+ init_waitqueue_head (& qsdev -> nondma_int_received_wq );
358
+ init_waitqueue_head (& qsdev -> report_desc_got_wq );
359
+ init_waitqueue_head (& qsdev -> get_report_cmpl_wq );
360
+ init_waitqueue_head (& qsdev -> set_report_cmpl_wq );
361
+
285
362
/* thc hw init */
286
363
qsdev -> thc_hw = thc_dev_init (qsdev -> dev , qsdev -> mem_addr );
287
364
if (IS_ERR (qsdev -> thc_hw )) {
@@ -290,6 +367,10 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
290
367
return ERR_PTR (ret );
291
368
}
292
369
370
+ ret = thc_interrupt_quiesce (qsdev -> thc_hw , true);
371
+ if (ret )
372
+ return ERR_PTR (ret );
373
+
293
374
ret = thc_port_select (qsdev -> thc_hw , THC_PORT_TYPE_SPI );
294
375
if (ret ) {
295
376
dev_err (dev , "Failed to select THC port, ret = %d.\n" , ret );
@@ -302,10 +383,43 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
302
383
return ERR_PTR (ret );
303
384
}
304
385
386
+ /* THC config for input/output address */
387
+ thc_spi_input_output_address_config (qsdev -> thc_hw ,
388
+ qsdev -> input_report_hdr_addr ,
389
+ qsdev -> input_report_bdy_addr ,
390
+ qsdev -> output_report_addr );
391
+
392
+ /* THC config for spi read operation */
393
+ ret = thc_spi_read_config (qsdev -> thc_hw , qsdev -> spi_freq_val ,
394
+ qsdev -> spi_read_io_mode ,
395
+ qsdev -> spi_read_opcode ,
396
+ qsdev -> spi_packet_size );
397
+ if (ret ) {
398
+ dev_err (dev , "thc_spi_read_config failed, ret = %d\n" , ret );
399
+ return ERR_PTR (ret );
400
+ }
401
+
402
+ /* THC config for spi write operation */
403
+ ret = thc_spi_write_config (qsdev -> thc_hw , qsdev -> spi_freq_val ,
404
+ qsdev -> spi_write_io_mode ,
405
+ qsdev -> spi_write_opcode ,
406
+ qsdev -> spi_packet_size ,
407
+ qsdev -> performance_limit );
408
+ if (ret ) {
409
+ dev_err (dev , "thc_spi_write_config failed, ret = %d\n" , ret );
410
+ return ERR_PTR (ret );
411
+ }
412
+
413
+ thc_ltr_config (qsdev -> thc_hw ,
414
+ qsdev -> active_ltr_val ,
415
+ qsdev -> low_power_ltr_val );
416
+
305
417
thc_interrupt_config (qsdev -> thc_hw );
306
418
307
419
thc_interrupt_enable (qsdev -> thc_hw , true);
308
420
421
+ qsdev -> state = QUICKSPI_INITED ;
422
+
309
423
return qsdev ;
310
424
}
311
425
@@ -319,6 +433,103 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
319
433
static void quickspi_dev_deinit (struct quickspi_device * qsdev )
320
434
{
321
435
thc_interrupt_enable (qsdev -> thc_hw , false);
436
+ thc_ltr_unconfig (qsdev -> thc_hw );
437
+
438
+ qsdev -> state = QUICKSPI_DISABLED ;
439
+ }
440
+
441
+ /**
442
+ * quickspi_dma_init - Configure THC DMA for quickspi device
443
+ * @qsdev: pointer to the quickspi device structure
444
+ *
445
+ * This function uses TIC's parameters(such as max input length, max output
446
+ * length) to allocate THC DMA buffers and configure THC DMA engines.
447
+ *
448
+ * Return: 0 if successful or error code on failed.
449
+ */
450
+ static int quickspi_dma_init (struct quickspi_device * qsdev )
451
+ {
452
+ int ret ;
453
+
454
+ ret = thc_dma_set_max_packet_sizes (qsdev -> thc_hw , 0 ,
455
+ le16_to_cpu (qsdev -> dev_desc .max_input_len ),
456
+ le16_to_cpu (qsdev -> dev_desc .max_output_len ),
457
+ 0 );
458
+ if (ret )
459
+ return ret ;
460
+
461
+ ret = thc_dma_allocate (qsdev -> thc_hw );
462
+ if (ret ) {
463
+ dev_err (qsdev -> dev , "Allocate THC DMA buffer failed, ret = %d\n" , ret );
464
+ return ret ;
465
+ }
466
+
467
+ /* Enable RxDMA */
468
+ ret = thc_dma_configure (qsdev -> thc_hw );
469
+ if (ret ) {
470
+ dev_err (qsdev -> dev , "Configure THC DMA failed, ret = %d\n" , ret );
471
+ thc_dma_unconfigure (qsdev -> thc_hw );
472
+ thc_dma_release (qsdev -> thc_hw );
473
+ return ret ;
474
+ }
475
+
476
+ return ret ;
477
+ }
478
+
479
+ /**
480
+ * quickspi_dma_deinit - Release THC DMA for quickspi device
481
+ * @qsdev: pointer to the quickspi device structure
482
+ *
483
+ * Stop THC DMA engines and release all DMA buffers.
484
+ *
485
+ */
486
+ static void quickspi_dma_deinit (struct quickspi_device * qsdev )
487
+ {
488
+ thc_dma_unconfigure (qsdev -> thc_hw );
489
+ thc_dma_release (qsdev -> thc_hw );
490
+ }
491
+
492
+ /**
493
+ * quickspi_alloc_report_buf - Alloc report buffers
494
+ * @qsdev: pointer to the quickspi device structure
495
+ *
496
+ * Allocate report descriptor buffer, it will be used for restore TIC HID
497
+ * report descriptor.
498
+ *
499
+ * Allocate input report buffer, it will be used for receive HID input report
500
+ * data from TIC.
501
+ *
502
+ * Allocate output report buffer, it will be used for store HID output report,
503
+ * such as set feature.
504
+ *
505
+ * Return: 0 if successful or error code on failed.
506
+ */
507
+ static int quickspi_alloc_report_buf (struct quickspi_device * qsdev )
508
+ {
509
+ size_t max_report_len ;
510
+ size_t max_input_len ;
511
+
512
+ qsdev -> report_descriptor = devm_kzalloc (qsdev -> dev ,
513
+ le16_to_cpu (qsdev -> dev_desc .rep_desc_len ),
514
+ GFP_KERNEL );
515
+ if (!qsdev -> report_descriptor )
516
+ return - ENOMEM ;
517
+
518
+ max_input_len = max (le16_to_cpu (qsdev -> dev_desc .rep_desc_len ),
519
+ le16_to_cpu (qsdev -> dev_desc .max_input_len ));
520
+
521
+ qsdev -> input_buf = devm_kzalloc (qsdev -> dev , max_input_len , GFP_KERNEL );
522
+ if (!qsdev -> input_buf )
523
+ return - ENOMEM ;
524
+
525
+ max_report_len = max (le16_to_cpu (qsdev -> dev_desc .max_output_len ),
526
+ le16_to_cpu (qsdev -> dev_desc .max_input_len ));
527
+
528
+ qsdev -> report_buf = devm_kzalloc (qsdev -> dev , max_report_len , GFP_KERNEL );
529
+ if (!qsdev -> report_buf )
530
+ return - ENOMEM ;
531
+
532
+ return 0 ;
322
533
}
323
534
324
535
/*
@@ -327,6 +538,18 @@ static void quickspi_dev_deinit(struct quickspi_device *qsdev)
327
538
* @pdev: point to pci device
328
539
* @id: point to pci_device_id structure
329
540
*
541
+ * This function initializes THC and HIDSPI device, the flow is:
542
+ * - do THC pci device initialization
543
+ * - query HIDSPI ACPI parameters
544
+ * - configure THC to HIDSPI mode
545
+ * - go through HIDSPI enumeration flow
546
+ * |- reset HIDSPI device
547
+ * |- read device descriptor
548
+ * - enable THC interrupt and DMA
549
+ * - read report descriptor
550
+ * - register HID device
551
+ * - enable runtime power management
552
+ *
330
553
* Return 0 if success or error code on failure.
331
554
*/
332
555
static int quickspi_probe (struct pci_dev * pdev ,
@@ -390,8 +613,44 @@ static int quickspi_probe(struct pci_dev *pdev,
390
613
goto dev_deinit ;
391
614
}
392
615
616
+ ret = reset_tic (qsdev );
617
+ if (ret ) {
618
+ dev_err (& pdev -> dev , "Reset Touch Device failed, ret = %d\n" , ret );
619
+ goto dev_deinit ;
620
+ }
621
+
622
+ ret = quickspi_alloc_report_buf (qsdev );
623
+ if (ret ) {
624
+ dev_err (& pdev -> dev , "Alloc report buffers failed, ret= %d\n" , ret );
625
+ goto dev_deinit ;
626
+ }
627
+
628
+ ret = quickspi_dma_init (qsdev );
629
+ if (ret ) {
630
+ dev_err (& pdev -> dev , "Setup THC DMA failed, ret= %d\n" , ret );
631
+ goto dev_deinit ;
632
+ }
633
+
634
+ ret = quickspi_get_report_descriptor (qsdev );
635
+ if (ret ) {
636
+ dev_err (& pdev -> dev , "Get report descriptor failed, ret = %d\n" , ret );
637
+ goto dma_deinit ;
638
+ }
639
+
640
+ ret = quickspi_hid_probe (qsdev );
641
+ if (ret ) {
642
+ dev_err (& pdev -> dev , "Failed to register HID device, ret = %d\n" , ret );
643
+ goto dma_deinit ;
644
+ }
645
+
646
+ qsdev -> state = QUICKSPI_ENABLED ;
647
+
648
+ dev_dbg (& pdev -> dev , "QuickSPI probe success\n" );
649
+
393
650
return 0 ;
394
651
652
+ dma_deinit :
653
+ quickspi_dma_deinit (qsdev );
395
654
dev_deinit :
396
655
quickspi_dev_deinit (qsdev );
397
656
unmap_io_region :
@@ -418,6 +677,9 @@ static void quickspi_remove(struct pci_dev *pdev)
418
677
if (!qsdev )
419
678
return ;
420
679
680
+ quickspi_hid_remove (qsdev );
681
+ quickspi_dma_deinit (qsdev );
682
+
421
683
quickspi_dev_deinit (qsdev );
422
684
423
685
pcim_iounmap_regions (pdev , BIT (0 ));
@@ -441,6 +703,9 @@ static void quickspi_shutdown(struct pci_dev *pdev)
441
703
if (!qsdev )
442
704
return ;
443
705
706
+ /* Must stop DMA before reboot to avoid DMA entering into unknown state */
707
+ quickspi_dma_deinit (qsdev );
708
+
444
709
quickspi_dev_deinit (qsdev );
445
710
}
446
711
0 commit comments