1414#include "intel-thc-hw.h"
1515
1616#include "quickspi-dev.h"
17+ #include "quickspi-hid.h"
18+ #include "quickspi-protocol.h"
1719
1820struct quickspi_driver_data mtl = {
1921 .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)
228230 return IRQ_WAKE_THREAD ;
229231}
230232
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+
231264/**
232265 * quickspi_irq_thread_handler - IRQ thread handler of quickspi driver
233266 *
@@ -239,15 +272,52 @@ static irqreturn_t quickspi_irq_quick_handler(int irq, void *dev_id)
239272static irqreturn_t quickspi_irq_thread_handler (int irq , void * dev_id )
240273{
241274 struct quickspi_device * qsdev = dev_id ;
275+ size_t input_len ;
276+ int read_finished = 0 ;
277+ int err_recover = 0 ;
242278 int int_mask ;
279+ int ret ;
243280
244281 if (qsdev -> state == QUICKSPI_DISABLED )
245282 return IRQ_HANDLED ;
246283
247284 int_mask = thc_interrupt_handler (qsdev -> thc_hw );
248285
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 :
249315 thc_interrupt_enable (qsdev -> thc_hw , true);
250316
317+ if (err_recover )
318+ if (try_recover (qsdev ))
319+ qsdev -> state = QUICKSPI_DISABLED ;
320+
251321 return IRQ_HANDLED ;
252322}
253323
@@ -280,8 +350,15 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
280350 qsdev -> pdev = pdev ;
281351 qsdev -> dev = dev ;
282352 qsdev -> mem_addr = mem_addr ;
353+ qsdev -> state = QUICKSPI_DISABLED ;
283354 qsdev -> driver_data = (struct quickspi_driver_data * )id -> driver_data ;
284355
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+
285362 /* thc hw init */
286363 qsdev -> thc_hw = thc_dev_init (qsdev -> dev , qsdev -> mem_addr );
287364 if (IS_ERR (qsdev -> thc_hw )) {
@@ -290,6 +367,10 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
290367 return ERR_PTR (ret );
291368 }
292369
370+ ret = thc_interrupt_quiesce (qsdev -> thc_hw , true);
371+ if (ret )
372+ return ERR_PTR (ret );
373+
293374 ret = thc_port_select (qsdev -> thc_hw , THC_PORT_TYPE_SPI );
294375 if (ret ) {
295376 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
302383 return ERR_PTR (ret );
303384 }
304385
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+
305417 thc_interrupt_config (qsdev -> thc_hw );
306418
307419 thc_interrupt_enable (qsdev -> thc_hw , true);
308420
421+ qsdev -> state = QUICKSPI_INITED ;
422+
309423 return qsdev ;
310424}
311425
@@ -319,6 +433,103 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
319433static void quickspi_dev_deinit (struct quickspi_device * qsdev )
320434{
321435 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 ;
322533}
323534
324535/*
@@ -327,6 +538,18 @@ static void quickspi_dev_deinit(struct quickspi_device *qsdev)
327538 * @pdev: point to pci device
328539 * @id: point to pci_device_id structure
329540 *
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+ *
330553 * Return 0 if success or error code on failure.
331554 */
332555static int quickspi_probe (struct pci_dev * pdev ,
@@ -390,8 +613,44 @@ static int quickspi_probe(struct pci_dev *pdev,
390613 goto dev_deinit ;
391614 }
392615
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+
393650 return 0 ;
394651
652+ dma_deinit :
653+ quickspi_dma_deinit (qsdev );
395654dev_deinit :
396655 quickspi_dev_deinit (qsdev );
397656unmap_io_region :
@@ -418,6 +677,9 @@ static void quickspi_remove(struct pci_dev *pdev)
418677 if (!qsdev )
419678 return ;
420679
680+ quickspi_hid_remove (qsdev );
681+ quickspi_dma_deinit (qsdev );
682+
421683 quickspi_dev_deinit (qsdev );
422684
423685 pcim_iounmap_regions (pdev , BIT (0 ));
@@ -441,6 +703,9 @@ static void quickspi_shutdown(struct pci_dev *pdev)
441703 if (!qsdev )
442704 return ;
443705
706+ /* Must stop DMA before reboot to avoid DMA entering into unknown state */
707+ quickspi_dma_deinit (qsdev );
708+
444709 quickspi_dev_deinit (qsdev );
445710}
446711
0 commit comments