/* ------------------------------------------------------------------------------------ * irdaeg file operation * ------------------------------------------------------------------------------------ */ static int irdaeg_fop_open(struct inode *inode, struct file *file) { int rc; printk( "%s:%d\n", __func__, __LINE__ ); printk( "%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); file->private_data = irdaeg_info ; /* Set IrDA mode at the MUX register at IrDA/Felica of PM8058 */ pm8058_misc_control(NULL, PM8058_UART_MUX_MASK, PM8058_UART_MUX_3); /* Set pm port */ rc = irda_eg_set_pm_port(); if(rc != 0){ printk( "Error set pm port\n" ); return rc; } printk( "%s:%d\n", __func__, __LINE__ ); return 0; }
static int msm_uart_aux_chg_irda( void ) { int rc = 0; // TX uart_tx2_en_22.function = PM_GPIO_FUNC_2; /* FUJITSU:2011-10-21 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { uart_tx2_en_22.out_strength = PM_GPIO_STRENGTH_MED; } #elif defined(CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { uart_tx2_en_22.out_strength = PM_GPIO_STRENGTH_MED; } #endif /* FUJITSU:2011-10-21 gpio chg end */ /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_gpio_config( PM8058_UART_TX2_22, &uart_tx2_en_22 ); #else rc = pm8xxx_gpio_config( PM8058_UART_TX2_22, &uart_tx2_en_22 ); #endif /* FUJITSU:2011-12-01 mod irda end */ if ( rc ) { printk( KERN_ERR "%s: PM8058_UART_TX config failed\n", __func__ ); return -EIO; } // RX /* FUJITSU:2011-09-28 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { uart_rx2_en_34.pull = PM_GPIO_PULL_UP_1P5; } #elif defined(CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { uart_rx2_en_34.pull = PM_GPIO_PULL_UP_1P5; } #endif /* FUJITSU:2011-09-28 gpio chg end */ /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_gpio_config( PM8058_UART_RX2_34, &uart_rx2_en_34 ); #else rc = pm8xxx_gpio_config( PM8058_UART_RX2_34, &uart_rx2_en_34 ); #endif /* FUJITSU:2011-12-01 mod irda end */ if ( rc ) { printk( KERN_ERR "%s: PM8058_UART_RX config failed\n", __func__ ); return -EIO; } // PMIC /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_misc_control( NULL, PM8058_UART_MUX_MASK, PM8058_UART_MUX_2 ); #else rc = pm8xxx_uart_gpio_mux_ctrl(UART_TX2_RX2); #endif /* FUJITSU:2011-12-01 mod irda end */ if ( rc ) { /* FUJITSU:2011-12-01 mod irda start */ #if 0 printk( KERN_ERR "%s:pmM8058_misc_control failed=%d\n", __func__, rc ); #else printk( KERN_ERR "%s:pm8xxx_uart_gpio_mux_ctrl failed=%d\n", __func__, rc ); #endif /* FUJITSU:2011-12-01 mod irda end */ } printk( KERN_INFO DEV_NAME " %s: UART Change -> IRDA\n", __func__ ); // TXD /* FUJITSU:2011-09-28 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { uart_pmic_txd_en_36.pull = PM_GPIO_PULL_UP_1P5; } #elif(defined CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { uart_pmic_txd_en_36.pull = PM_GPIO_PULL_UP_1P5; } #endif /* FUJITSU:2011-09-28 gpio chg end */ /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_gpio_config( PM8058_UART_PMIC_TXD_36, &uart_pmic_txd_en_36 ); #else rc = pm8xxx_gpio_config( PM8058_UART_PMIC_TXD_36, &uart_pmic_txd_en_36 ); #endif /* FUJITSU:2011-12-01 mod irda end */ if ( rc ) { printk( KERN_ERR "%s: PM8058_UART_PMIC_TXD config failed\n", __func__ ); return -EIO; } // RXD /* FUJITSU:2011-09-28 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { uart_pmic_rxd_en_37.out_strength = PM_GPIO_STRENGTH_MED; uart_pmic_rxd_en_37.pull = PM_GPIO_PULL_UP_1P5; } #elif defined(CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { uart_pmic_rxd_en_37.out_strength = PM_GPIO_STRENGTH_MED; uart_pmic_rxd_en_37.pull = PM_GPIO_PULL_UP_1P5; } #endif /* FUJITSU:2011-09-28 gpio chg end */ /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_gpio_config( PM8058_UART_PMIC_RXD_37, &uart_pmic_rxd_en_37 ); #else rc = pm8xxx_gpio_config( PM8058_UART_PMIC_RXD_37, &uart_pmic_rxd_en_37 ); #endif /* FUJITSU:2011-12-01 mod irda end */ if ( rc ) { printk( KERN_ERR "%s: PM8058_UART_PMIC_RXD config failed\n", __func__ ); return -EIO; } // MSM rc = gpio_tlmm_config( GPIO_CFG( 51, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); if ( rc ) { printk( KERN_ERR "%s: MSM8655_UART_RXD_A config failed\n", __func__ ); return -EIO; } /* FUJITSU:2011-09-28 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); }else{ rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); } #elif defined(CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); }else{ rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); } #else rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE ); #endif /* FUJITSU:2011-09-28 gpio chg end */ if ( rc ) { printk( KERN_ERR "%s: MSM8655_UART_TXD_A config failed\n", __func__ ); return -EIO; } // SD /* FUJITSU:2011-09-28 gpio chg start */ #if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON) if((system_rev != 0x08) || (system_rev != 0x0F)) { irda_pwdown_26.output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN; irda_pwdown_26.out_strength = PM_GPIO_STRENGTH_NO; } #elif defined(CONFIG_MACH_FJI12) if((system_rev != 0x00) || (system_rev != 0x07)) { irda_pwdown_26.output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN; irda_pwdown_26.out_strength = PM_GPIO_STRENGTH_NO; } #endif /* FUJITSU:2011-09-28 gpio chg end */ /* FUJITSU:2011-12-01 mod irda start */ #if 0 rc = pm8058_gpio_config( PM8058_IRDA_PWD_26, &irda_pwdown_26 ); #else rc = pm8xxx_gpio_config( PM8058_IRDA_PWD_26, &irda_pwdown_26 ); #endif /* FUJITSU:2011-12-01 mod irda end */ if( rc < 0 ) { printk( KERN_ERR "%s: PM8058_IRDA_PWD_26 config failed[%d]\n", __func__, rc ); return -EIO; } printk( KERN_INFO DEV_NAME " %s: IRDA GPIO Config Complete\n", __func__ ); return 0; }
static int irda_uart_release(struct inode *inode, struct file *file) { down(&irc->sem); printk(KERN_INFO DRV_NAME ": %s\n", __func__); /* Decrement refcount */ irc->refcount--; /* Check refcount */ if (irc->refcount == 0) { /* do discard flush */ if (irc->rx_state == IRDA_RX_START) { irc->rx_state = IRDA_RX_IDLE; msm_dmov_stop_cmd(irc->pfdata->chan_uartdm_rx, &irc->rxdmov_cmd, 0); } /* Deactivate RXLEV IRQ */ irc->imr_reg &= ~BIT_RXLEV; msm_uartdm_write(UARTDM_IMR, irc->imr_reg); /* (state change)--> IRDA_UART_OPEN */ irc->state = IRDA_UART_CLOSE; /* Disable the IRDA transceiver */ msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE); /* Disable Transmitter and Receiver */ msm_uartdm_write(UARTDM_CR, BIT_UART_TX_DISABLE); msm_uartdm_write(UARTDM_CR, BIT_UART_RX_DISABLE); /* Desable TXDM and RXDM mode */ msm_uartdm_write(UARTDM_DMEN, IRUART_IRDA_DISABLE); /* Wait 1usec */ udelay(1); /* Setting PM power off (Hig) */ pm8058_gpio_config(irc->pfdata->gpio_pow, irc->pfdata->gpio_pwcfg_hig); /* Clear UART SW buffer */ irda_txbuf_clear(&irc->txbuf); irda_rxbuf_clear(&irc->rxbuf); /* Reset TX and RX*/ msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER); msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER); msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS); msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT); /* Release DMOV data */ dma_free_coherent(NULL, sizeof(dmov_box), irc->txbox, irc->mapped_txbox); dma_free_coherent(NULL, sizeof(dmov_box), irc->rxbox, irc->mapped_rxbox); dma_free_coherent(NULL, sizeof(u32 *), irc->txbox_ptr, irc->mapped_txbox_ptr); dma_free_coherent(NULL, sizeof(u32 *), irc->rxbox_ptr, irc->mapped_rxbox_ptr); /* UARTDM clock stop */ clk_disable(irc->clk_uartdm); /* UARTDM iounmap */ if (irc->iores_uartdm) release_mem_region((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE); iounmap(irc->vaddr_uartdm); /* Remove IRQ for UARTDM */ free_irq(irc->pfdata->irq_uartdm, irc); /* Remove tasklets for UARTDM */ tasklet_kill(&irc->tasklet_rxfer_s); tasklet_kill(&irc->tasklet_rxfer_e); tasklet_kill(&irc->tasklet_txfer); /* PM8058 UART MUX reset */ pm8058_misc_control(irc->nfcdev->pm_chip, PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO); { u8 misc = 0x0; int ret = pm8058_read(irc->nfcdev->pm_chip, SSBI_REG_ADDR_MISC, &misc, 1); if (ret) printk(KERN_ERR DRV_NAME ": cannot read pm8058 UART MUX reg.\n"); else printk(KERN_INFO DRV_NAME ": misc register = %x\n", misc); } } printk(KERN_INFO DRV_NAME ": Closed. Refcount = %d\n", irc->refcount); up(&irc->sem); return 0; }
static int irda_uart_open(struct inode *inode, struct file *file) { int ret; u8 misc = 0x0; down(&irc->sem); printk(KERN_INFO DRV_NAME ": %s\n", __func__); /* Check refcount */ if (irc->refcount > 0) { irc->refcount++; printk(KERN_INFO DRV_NAME ": refirence counter count up(%d).\n", irc->refcount); up(&irc->sem); return 0; } /* PM8058-NFC Request */ irc->nfcdev = pm8058_nfc_request(); if (irc->nfcdev == NULL) { printk(KERN_ERR DRV_NAME ": pm8058 nfc not found.\n"); ret = -ENODEV; goto error_pm_nfc_request; } /* PM8058 UART MUX setting */ ret = pm8058_read(irc->nfcdev->pm_chip, SSBI_REG_ADDR_MISC, &misc, 1); if (ret) printk(KERN_ERR DRV_NAME ": cannot read pm8058 UART MUX reg.\n"); else printk(KERN_INFO DRV_NAME ": misc register = %x\n", misc); misc &= PM8058_UART_MUX_MASK; switch (misc) { case PM8058_UART_MUX_NO: pm8058_misc_control(irc->nfcdev->pm_chip, PM8058_UART_MUX_MASK, PM8058_UART_MUX_3); printk(KERN_INFO DRV_NAME ": OK. UART MUX = neutral --> IrDA.\n"); break; case PM8058_UART_MUX_1: printk(KERN_ERR DRV_NAME ": Now, uart_mux = 1 (FeliCa)\n"); ret = -EBUSY; goto err_set_uart_mux; case PM8058_UART_MUX_2: printk(KERN_ERR DRV_NAME ": Now, uart_mux = 2 (unknown)\n"); ret = -EBUSY; goto err_set_uart_mux; default: printk(KERN_ERR DRV_NAME ": UART MUX unavaible.\n"); ret = -EIO; goto err_set_uart_mux; } /* init IMR value */ irc->imr_reg = 0x0; /* init wait queue */ init_waitqueue_head(&irc->wait_tx); init_waitqueue_head(&irc->wait_rx); /* init tasklet */ tasklet_init(&irc->tasklet_rxfer_s, irda_uart_rxfer_start, 0); tasklet_init(&irc->tasklet_rxfer_e, irda_uart_rxfer_end, 0); tasklet_init(&irc->tasklet_txfer, irda_uart_txfer_exec, 0); /* Register UARTDM IRQ */ ret = request_irq(irc->pfdata->irq_uartdm, irda_uart_irq_handler, IRQF_TRIGGER_HIGH, "irda_uart", irc); if (ret) { printk(KERN_ERR DRV_NAME ": request IRQ failed. (UARTDM)\n"); goto err_request_irq_uart; } /* UARTDM ioremap */ /* memory protection */ irc->iores_uartdm = request_mem_region((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE, "irda_uart"); if (!irc->iores_uartdm) { printk(KERN_ERR DRV_NAME ": UARTDM request_mem_region failed.\n"); ret = -EBUSY; goto err_request_mem_region; } irc->vaddr_uartdm = ioremap_nocache((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE); if (!irc->vaddr_uartdm) { printk(KERN_ERR DRV_NAME ": UARTDM ioremap failed.\n"); ret = -ENOMEM; goto err_ioremap_uartdm; } /* UARTDM clock set and start */ /* default 9600 bps */ irc->bps = 9600; clk_set_rate(irc->clk_uartdm, IRUART_UARTDM_CLK(9600)); clk_enable(irc->clk_uartdm); msm_uartdm_write(UARTDM_CSR, IRUART_DEF_BAUDRATE_CSR); /* UARTDM register setting */ /* Data-stop-parity setting (MR2) */ msm_uartdm_write(UARTDM_MR2, IRUART_DATA_STOP_PARITY); /* RX&TX wartermark setting */ msm_uartdm_write(UARTDM_TFWR, 0x0); msm_uartdm_write(UARTDM_RFWR, 0x0); /* Stale time-out setting */ msm_uartdm_write(UARTDM_IPR, (IRUART_DEF_RXSTALE & BIT_STALE_TIMEOUT_LSB) | ((IRUART_DEF_RXSTALE << 2) & BIT_STALE_TIMEOUT_MSB)); /* Enable TXDM and RXDM mode */ msm_uartdm_write(UARTDM_DMEN, BIT_RX_DM_EN|BIT_TX_DM_EN); /* Enable the IRDA transceiver */ msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_EN); /* TX DMOV mapping */ irc->txbox = dma_alloc_coherent(NULL, sizeof(dmov_box), &irc->mapped_txbox, GFP_KERNEL); if (!irc->txbox) { printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(1).\n"); ret = -ENOMEM; goto err_alloc_txbox; } irc->txbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *), &irc->mapped_txbox_ptr, GFP_KERNEL); if (!irc->txbox_ptr) { printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(2).\n"); ret = -ENOMEM; goto err_alloc_txbox_ptr; } *irc->txbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_txbox); irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr); irc->txdmov_cmd.complete_func = irda_txdmov_callback; irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr); irc->txbox->cmd = CMD_LC | CMD_DST_CRCI(irc->pfdata->crci_uartdm_tx) | CMD_MODE_BOX; /* TX DMOV BOX command */ irc->txbox->src_row_addr = 0x0; irc->txbox->dst_row_addr = (u32)irc->pfdata->paddr_uartdm + UARTDM_TF; irc->txbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE; irc->txbox->num_rows = 0x0; irc->txbox->row_offset = (UARTDM_BURST_SIZE<<16); /* RX DMOV mapping */ irc->rxbox = dma_alloc_coherent(NULL, sizeof(dmov_box), &irc->mapped_rxbox, GFP_KERNEL); if (!irc->rxbox) { printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(1).\n"); ret = -ENOMEM; goto err_alloc_rxbox; } irc->rxbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *), &irc->mapped_rxbox_ptr, GFP_KERNEL); if (!irc->rxbox_ptr) { printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(2).\n"); ret = -ENOMEM; goto err_alloc_rxbox_ptr; } *irc->rxbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_rxbox); irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr); irc->rxdmov_cmd.complete_func = irda_rxdmov_callback; irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr); irc->rxbox->cmd = CMD_LC | CMD_SRC_CRCI(irc->pfdata->crci_uartdm_rx) | CMD_MODE_BOX; /* RX DMOV BOX command */ irc->rxbox->src_row_addr = (u32)irc->pfdata->paddr_uartdm + UARTDM_RF; irc->rxbox->dst_row_addr = 0x0; irc->rxbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE; irc->rxbox->num_rows = (IRUART_SW_RXBUF_SIZE >> 4 << 16) | IRUART_SW_RXBUF_SIZE >> 4; irc->rxbox->row_offset = UARTDM_BURST_SIZE; /* Enable Command Register Protection */ msm_uartdm_write(UARTDM_CR, GCMD_CR_PROTECTION_ENABLE); /* Reset TX and RX */ msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER); msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER); msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS); msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT); /* Setting PM power on (Low) */ ret = pm8058_gpio_config(irc->pfdata->gpio_pow, irc->pfdata->gpio_pwcfg_low); if (ret) { printk(KERN_ERR DRV_NAME ": pmic gpio write failed\n"); goto err_gpio_config; } /* Wait 200usec */ udelay(200); /* Enable Transmitter and Receiver */ msm_uartdm_write(UARTDM_CR, BIT_UART_TX_EN); msm_uartdm_write(UARTDM_CR, BIT_UART_RX_EN); /* Clear UART SW buffer */ irda_txbuf_clear(&irc->txbuf); irda_rxbuf_clear(&irc->rxbuf); /* init Overflow flag */ irc->rx_overflow = IRDA_NORMAL; /* Increment refcount */ irc->refcount++; /* (state change)--> IRDA_UART_OPEN */ irc->state = IRDA_UART_OPEN; irc->rx_state = IRDA_RX_IDLE; printk(KERN_INFO DRV_NAME ": succecssfly opened, refcount = %d\n", irc->refcount); /* Activate RXLEV IRQ */ irc->imr_reg |= BIT_RXLEV; msm_uartdm_write(UARTDM_IMR, irc->imr_reg); up(&irc->sem); return 0; /* Error handling */ err_gpio_config: dma_free_coherent(NULL, sizeof(u32 *), irc->rxbox_ptr, irc->mapped_txbox_ptr); err_alloc_rxbox_ptr: dma_free_coherent(NULL, sizeof(dmov_box), irc->rxbox, irc->mapped_rxbox); err_alloc_rxbox: dma_free_coherent(NULL, sizeof(u32 *), irc->txbox_ptr, irc->mapped_txbox_ptr); err_alloc_txbox_ptr: dma_free_coherent(NULL, sizeof(dmov_box), irc->txbox, irc->mapped_txbox); err_alloc_txbox: msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE); clk_disable(irc->clk_uartdm); iounmap(irc->vaddr_uartdm); err_ioremap_uartdm: release_mem_region((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE); err_request_mem_region: free_irq(irc->pfdata->irq_uartdm, irc); err_request_irq_uart: tasklet_kill(&irc->tasklet_rxfer_s); tasklet_kill(&irc->tasklet_rxfer_e); tasklet_kill(&irc->tasklet_txfer); pm8058_misc_control(irc->nfcdev->pm_chip, PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO); err_set_uart_mux: error_pm_nfc_request: up(&irc->sem); return ret; }