1 /* 2 * netup_unidvb_ci.c 3 * 4 * DVB CAM support for NetUP Universal Dual DVB-CI 5 * 6 * Copyright (C) 2014 NetUP Inc. 7 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru> 8 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21 #include <linux/init.h> 22 #include <linux/module.h> 23 #include <linux/moduleparam.h> 24 #include <linux/kmod.h> 25 #include <linux/kernel.h> 26 #include <linux/slab.h> 27 #include <linux/interrupt.h> 28 #include <linux/delay.h> 29 #include "netup_unidvb.h" 30 31 /* CI slot 0 base address */ 32 #define CAM0_CONFIG 0x0 33 #define CAM0_IO 0x8000 34 #define CAM0_MEM 0x10000 35 #define CAM0_SZ 32 36 /* CI slot 1 base address */ 37 #define CAM1_CONFIG 0x20000 38 #define CAM1_IO 0x28000 39 #define CAM1_MEM 0x30000 40 #define CAM1_SZ 32 41 /* ctrlstat registers */ 42 #define CAM_CTRLSTAT_READ_SET 0x4980 43 #define CAM_CTRLSTAT_CLR 0x4982 44 /* register bits */ 45 #define BIT_CAM_STCHG (1<<0) 46 #define BIT_CAM_PRESENT (1<<1) 47 #define BIT_CAM_RESET (1<<2) 48 #define BIT_CAM_BYPASS (1<<3) 49 #define BIT_CAM_READY (1<<4) 50 #define BIT_CAM_ERROR (1<<5) 51 #define BIT_CAM_OVERCURR (1<<6) 52 /* BIT_CAM_BYPASS bit shift for SLOT 1 */ 53 #define CAM1_SHIFT 8 54 55 irqreturn_t netup_ci_interrupt(struct netup_unidvb_dev *ndev) 56 { 57 writew(0x101, ndev->bmmio0 + CAM_CTRLSTAT_CLR); 58 return IRQ_HANDLED; 59 } 60 61 static int netup_unidvb_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, 62 int slot) 63 { 64 struct netup_ci_state *state = en50221->data; 65 struct netup_unidvb_dev *dev = state->dev; 66 u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0; 67 68 dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT=0x%x\n", 69 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET)); 70 if (slot != 0) 71 return -EINVAL; 72 /* pass data to CAM module */ 73 writew(BIT_CAM_BYPASS << shift, dev->bmmio0 + CAM_CTRLSTAT_CLR); 74 dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT=0x%x done\n", 75 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET)); 76 return 0; 77 } 78 79 static int netup_unidvb_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, 80 int slot) 81 { 82 struct netup_ci_state *state = en50221->data; 83 struct netup_unidvb_dev *dev = state->dev; 84 85 dev_dbg(&dev->pci_dev->dev, "%s()\n", __func__); 86 return 0; 87 } 88 89 static int netup_unidvb_ci_slot_reset(struct dvb_ca_en50221 *en50221, 90 int slot) 91 { 92 struct netup_ci_state *state = en50221->data; 93 struct netup_unidvb_dev *dev = state->dev; 94 unsigned long timeout = 0; 95 u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0; 96 u16 ci_stat = 0; 97 int reset_counter = 3; 98 99 dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n", 100 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET)); 101 reset: 102 timeout = jiffies + msecs_to_jiffies(5000); 103 /* start reset */ 104 writew(BIT_CAM_RESET << shift, dev->bmmio0 + CAM_CTRLSTAT_READ_SET); 105 dev_dbg(&dev->pci_dev->dev, "%s(): waiting for reset\n", __func__); 106 /* wait until reset done */ 107 while (time_before(jiffies, timeout)) { 108 ci_stat = readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET); 109 if (ci_stat & (BIT_CAM_READY << shift)) 110 break; 111 udelay(1000); 112 } 113 if (!(ci_stat & (BIT_CAM_READY << shift)) && reset_counter > 0) { 114 dev_dbg(&dev->pci_dev->dev, 115 "%s(): CAMP reset timeout! Will try again..\n", 116 __func__); 117 reset_counter--; 118 goto reset; 119 } 120 return 0; 121 } 122 123 static int netup_unidvb_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, 124 int slot, int open) 125 { 126 struct netup_ci_state *state = en50221->data; 127 struct netup_unidvb_dev *dev = state->dev; 128 u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0; 129 u16 ci_stat = 0; 130 131 dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n", 132 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET)); 133 ci_stat = readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET); 134 if (ci_stat & (BIT_CAM_READY << shift)) { 135 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | 136 DVB_CA_EN50221_POLL_CAM_READY; 137 } else if (ci_stat & (BIT_CAM_PRESENT << shift)) { 138 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT; 139 } else { 140 state->status = 0; 141 } 142 return state->status; 143 } 144 145 static int netup_unidvb_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, 146 int slot, int addr) 147 { 148 struct netup_ci_state *state = en50221->data; 149 struct netup_unidvb_dev *dev = state->dev; 150 u8 val = *((u8 __force *)state->membase8_config + addr); 151 152 dev_dbg(&dev->pci_dev->dev, 153 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val); 154 return val; 155 } 156 157 static int netup_unidvb_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, 158 int slot, int addr, u8 data) 159 { 160 struct netup_ci_state *state = en50221->data; 161 struct netup_unidvb_dev *dev = state->dev; 162 163 dev_dbg(&dev->pci_dev->dev, 164 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data); 165 *((u8 __force *)state->membase8_config + addr) = data; 166 return 0; 167 } 168 169 static int netup_unidvb_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, 170 int slot, u8 addr) 171 { 172 struct netup_ci_state *state = en50221->data; 173 struct netup_unidvb_dev *dev = state->dev; 174 u8 val = *((u8 __force *)state->membase8_io + addr); 175 176 dev_dbg(&dev->pci_dev->dev, 177 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val); 178 return val; 179 } 180 181 static int netup_unidvb_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, 182 int slot, u8 addr, u8 data) 183 { 184 struct netup_ci_state *state = en50221->data; 185 struct netup_unidvb_dev *dev = state->dev; 186 187 dev_dbg(&dev->pci_dev->dev, 188 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data); 189 *((u8 __force *)state->membase8_io + addr) = data; 190 return 0; 191 } 192 193 int netup_unidvb_ci_register(struct netup_unidvb_dev *dev, 194 int num, struct pci_dev *pci_dev) 195 { 196 int result; 197 struct netup_ci_state *state; 198 199 if (num < 0 || num > 1) { 200 dev_err(&pci_dev->dev, "%s(): invalid CI adapter %d\n", 201 __func__, num); 202 return -EINVAL; 203 } 204 state = &dev->ci[num]; 205 state->nr = num; 206 state->membase8_config = dev->bmmio1 + 207 ((num == 0) ? CAM0_CONFIG : CAM1_CONFIG); 208 state->membase8_io = dev->bmmio1 + 209 ((num == 0) ? CAM0_IO : CAM1_IO); 210 state->dev = dev; 211 state->ca.owner = THIS_MODULE; 212 state->ca.read_attribute_mem = netup_unidvb_ci_read_attribute_mem; 213 state->ca.write_attribute_mem = netup_unidvb_ci_write_attribute_mem; 214 state->ca.read_cam_control = netup_unidvb_ci_read_cam_ctl; 215 state->ca.write_cam_control = netup_unidvb_ci_write_cam_ctl; 216 state->ca.slot_reset = netup_unidvb_ci_slot_reset; 217 state->ca.slot_shutdown = netup_unidvb_ci_slot_shutdown; 218 state->ca.slot_ts_enable = netup_unidvb_ci_slot_ts_ctl; 219 state->ca.poll_slot_status = netup_unidvb_poll_ci_slot_status; 220 state->ca.data = state; 221 result = dvb_ca_en50221_init(&dev->frontends[num].adapter, 222 &state->ca, 0, 1); 223 if (result < 0) { 224 dev_err(&pci_dev->dev, 225 "%s(): dvb_ca_en50221_init result %d\n", 226 __func__, result); 227 return result; 228 } 229 writew(NETUP_UNIDVB_IRQ_CI, dev->bmmio0 + REG_IMASK_SET); 230 dev_info(&pci_dev->dev, 231 "%s(): CI adapter %d init done\n", __func__, num); 232 return 0; 233 } 234 235 void netup_unidvb_ci_unregister(struct netup_unidvb_dev *dev, int num) 236 { 237 struct netup_ci_state *state; 238 239 dev_dbg(&dev->pci_dev->dev, "%s()\n", __func__); 240 if (num < 0 || num > 1) { 241 dev_err(&dev->pci_dev->dev, "%s(): invalid CI adapter %d\n", 242 __func__, num); 243 return; 244 } 245 state = &dev->ci[num]; 246 dvb_ca_en50221_release(&state->ca); 247 } 248 249