blob: 403ce043d00e7a91b4bf7564806468eb3dbea4ea [file] [log] [blame]
Manu Abraham50d82602009-12-04 05:06:38 -03001/*
2 Mantis PCI bridge driver
3
Manu Abraham8825a092009-12-15 09:13:49 -03004 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
Manu Abraham50d82602009-12-04 05:06:38 -03005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
Manu Abrahamb3b96142009-12-04 05:41:11 -030021#include <linux/signal.h>
22#include <linux/sched.h>
23#include <linux/interrupt.h>
24
25#include "dmxdev.h"
26#include "dvbdev.h"
27#include "dvb_demux.h"
28#include "dvb_frontend.h"
29#include "dvb_net.h"
30
Manu Abraham50d82602009-12-04 05:06:38 -030031#include "mantis_common.h"
32#include "mantis_link.h"
33#include "mantis_hif.h"
Manu Abrahamb3b96142009-12-04 05:41:11 -030034#include "mantis_reg.h"
35
36#include "mantis_ca.h"
Manu Abraham50d82602009-12-04 05:06:38 -030037
Manu Abraham60532402009-12-04 05:11:14 -030038static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
39{
40 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030041 struct mantis_pci *mantis = ca->ca_priv;
42
Manu Abrahamb3b96142009-12-04 05:41:11 -030043 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
Manu Abraham50d82602009-12-04 05:06:38 -030044
Manu Abraham60532402009-12-04 05:11:14 -030045 if (slot != 0)
46 return -EINVAL;
47
48 return mantis_hif_read_mem(ca, addr);
49}
50
51static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
52{
53 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030054 struct mantis_pci *mantis = ca->ca_priv;
55
Manu Abrahamb3b96142009-12-04 05:41:11 -030056 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
Manu Abraham60532402009-12-04 05:11:14 -030057
58 if (slot != 0)
59 return -EINVAL;
60
61 return mantis_hif_write_mem(ca, addr, data);
62}
63
64static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
65{
66 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030067 struct mantis_pci *mantis = ca->ca_priv;
68
Manu Abrahamb3b96142009-12-04 05:41:11 -030069 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
Manu Abraham60532402009-12-04 05:11:14 -030070
71 if (slot != 0)
72 return -EINVAL;
73
74 return mantis_hif_read_iom(ca, addr);
75}
76
77static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
78{
79 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030080 struct mantis_pci *mantis = ca->ca_priv;
81
Manu Abrahamb3b96142009-12-04 05:41:11 -030082 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
Manu Abraham60532402009-12-04 05:11:14 -030083
84 if (slot != 0)
85 return -EINVAL;
86
87 return mantis_hif_write_iom(ca, addr, data);
88}
89
90static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -030091{
Manu Abraham2133ffb2009-12-04 05:12:16 -030092 struct mantis_ca *ca = en50221->data;
93 struct mantis_pci *mantis = ca->ca_priv;
94
Manu Abrahamb3b96142009-12-04 05:41:11 -030095 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
Manu Abrahamfb6de9c2009-12-04 05:17:46 -030096 udelay(500); /* Wait.. */
97 mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
98 udelay(500);
99 mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
100 msleep(1000);
Manu Abraham2ec9b002009-12-04 05:20:44 -0300101 dvb_ca_en50221_camready_irq(&ca->en50221, 0);
Manu Abraham2133ffb2009-12-04 05:12:16 -0300102
Manu Abraham50d82602009-12-04 05:06:38 -0300103 return 0;
104}
105
Manu Abraham60532402009-12-04 05:11:14 -0300106static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -0300107{
Manu Abraham2133ffb2009-12-04 05:12:16 -0300108 struct mantis_ca *ca = en50221->data;
109 struct mantis_pci *mantis = ca->ca_priv;
110
Manu Abrahamb3b96142009-12-04 05:41:11 -0300111 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
Manu Abraham2133ffb2009-12-04 05:12:16 -0300112
Manu Abraham50d82602009-12-04 05:06:38 -0300113 return 0;
114}
115
Manu Abraham60532402009-12-04 05:11:14 -0300116static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -0300117{
Manu Abraham2133ffb2009-12-04 05:12:16 -0300118 struct mantis_ca *ca = en50221->data;
119 struct mantis_pci *mantis = ca->ca_priv;
120
Manu Abrahamb3b96142009-12-04 05:41:11 -0300121 dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
Manu Abrahamf5ae4f62009-12-15 08:47:21 -0300122/* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */
Manu Abraham2133ffb2009-12-04 05:12:16 -0300123
Manu Abraham50d82602009-12-04 05:06:38 -0300124 return 0;
125}
126
Manu Abraham60532402009-12-04 05:11:14 -0300127static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
Manu Abraham50d82602009-12-04 05:06:38 -0300128{
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300129 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -0300130 struct mantis_pci *mantis = ca->ca_priv;
131
Manu Abrahamb3b96142009-12-04 05:41:11 -0300132 dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300133
Manu Abraham5e2a0c92009-12-04 05:23:17 -0300134 if (ca->slot_state == MODULE_INSERTED) {
Manu Abrahamb3b96142009-12-04 05:41:11 -0300135 dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300136 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
Manu Abraham5e2a0c92009-12-04 05:23:17 -0300137 } else {
Manu Abrahamb3b96142009-12-04 05:41:11 -0300138 dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
Manu Abraham5e2a0c92009-12-04 05:23:17 -0300139 }
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300140
Manu Abraham50d82602009-12-04 05:06:38 -0300141 return 0;
Manu Abraham50d82602009-12-04 05:06:38 -0300142}
143
Manu Abraham60532402009-12-04 05:11:14 -0300144int mantis_ca_init(struct mantis_pci *mantis)
Manu Abraham50d82602009-12-04 05:06:38 -0300145{
Manu Abrahamb3b96142009-12-04 05:41:11 -0300146 struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter;
Manu Abraham50d82602009-12-04 05:06:38 -0300147 struct mantis_ca *ca;
Manu Abraham60532402009-12-04 05:11:14 -0300148 int ca_flags = 0, result;
Manu Abraham50d82602009-12-04 05:06:38 -0300149
Manu Abrahamb3b96142009-12-04 05:41:11 -0300150 dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
Manu Abrahamf5ae4f62009-12-15 08:47:21 -0300151 ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
Manu Abrahamb3b96142009-12-04 05:41:11 -0300152 if (!ca) {
153 dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
Manu Abraham60532402009-12-04 05:11:14 -0300154 result = -ENOMEM;
155 goto err;
Manu Abraham50d82602009-12-04 05:06:38 -0300156 }
157
Manu Abrahamb3b96142009-12-04 05:41:11 -0300158 ca->ca_priv = mantis;
159 mantis->mantis_ca = ca;
160 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
Manu Abraham60532402009-12-04 05:11:14 -0300161 /* register CA interface */
162 ca->en50221.owner = THIS_MODULE;
163 ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem;
164 ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem;
165 ca->en50221.read_cam_control = mantis_ca_read_cam_ctl;
166 ca->en50221.write_cam_control = mantis_ca_write_cam_ctl;
167 ca->en50221.slot_reset = mantis_ca_slot_reset;
168 ca->en50221.slot_shutdown = mantis_ca_slot_shutdown;
169 ca->en50221.slot_ts_enable = mantis_ts_control;
170 ca->en50221.poll_slot_status = mantis_slot_status;
171 ca->en50221.data = ca;
172
Manu Abraham99b55b22009-12-04 05:34:44 -0300173 mutex_init(&ca->ca_lock);
174
Manu Abraham42f541b2009-12-04 05:35:07 -0300175 init_waitqueue_head(&ca->hif_data_wq);
176 init_waitqueue_head(&ca->hif_opdone_wq);
177 init_waitqueue_head(&ca->hif_write_wq);
178
Manu Abrahamb3b96142009-12-04 05:41:11 -0300179 dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
180 result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
181 if (result != 0) {
182 dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
Manu Abraham60532402009-12-04 05:11:14 -0300183 goto err;
Manu Abraham50d82602009-12-04 05:06:38 -0300184 }
Manu Abrahamb3b96142009-12-04 05:41:11 -0300185 dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
Manu Abraham60532402009-12-04 05:11:14 -0300186 mantis_evmgr_init(ca);
Manu Abraham50d82602009-12-04 05:06:38 -0300187 return 0;
Manu Abraham60532402009-12-04 05:11:14 -0300188err:
189 kfree(ca);
190 return result;
Manu Abraham50d82602009-12-04 05:06:38 -0300191}
Manu Abrahamb3b96142009-12-04 05:41:11 -0300192EXPORT_SYMBOL_GPL(mantis_ca_init);
Manu Abraham50d82602009-12-04 05:06:38 -0300193
194void mantis_ca_exit(struct mantis_pci *mantis)
195{
196 struct mantis_ca *ca = mantis->mantis_ca;
Manu Abraham2133ffb2009-12-04 05:12:16 -0300197
Manu Abrahamb3b96142009-12-04 05:41:11 -0300198 dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
Manu Abraham50d82602009-12-04 05:06:38 -0300199
200 mantis_evmgr_exit(ca);
Manu Abrahamb3b96142009-12-04 05:41:11 -0300201 dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
202 if (ca)
203 dvb_ca_en50221_release(&ca->en50221);
Manu Abraham50d82602009-12-04 05:06:38 -0300204
205 kfree(ca);
206}
Manu Abrahamb3b96142009-12-04 05:41:11 -0300207EXPORT_SYMBOL_GPL(mantis_ca_exit);