blob: 53c01b3023ccb228997814659f61c894f3eff437 [file] [log] [blame]
Manu Abraham50d82602009-12-04 05:06:38 -03001/*
2 Mantis PCI bridge driver
3
4 Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.com)
5
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
21#include "mantis_common.h"
22#include "mantis_link.h"
23#include "mantis_hif.h"
24
Manu Abraham60532402009-12-04 05:11:14 -030025static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
26{
27 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030028 struct mantis_pci *mantis = ca->ca_priv;
29
30 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
Manu Abraham50d82602009-12-04 05:06:38 -030031
Manu Abraham60532402009-12-04 05:11:14 -030032 if (slot != 0)
33 return -EINVAL;
34
35 return mantis_hif_read_mem(ca, addr);
36}
37
38static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
39{
40 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030041 struct mantis_pci *mantis = ca->ca_priv;
42
43 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
Manu Abraham60532402009-12-04 05:11:14 -030044
45 if (slot != 0)
46 return -EINVAL;
47
48 return mantis_hif_write_mem(ca, addr, data);
49}
50
51static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
52{
53 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030054 struct mantis_pci *mantis = ca->ca_priv;
55
56 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
Manu Abraham60532402009-12-04 05:11:14 -030057
58 if (slot != 0)
59 return -EINVAL;
60
61 return mantis_hif_read_iom(ca, addr);
62}
63
64static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
65{
66 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -030067 struct mantis_pci *mantis = ca->ca_priv;
68
69 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
Manu Abraham60532402009-12-04 05:11:14 -030070
71 if (slot != 0)
72 return -EINVAL;
73
74 return mantis_hif_write_iom(ca, addr, data);
75}
76
77static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -030078{
Manu Abraham2133ffb2009-12-04 05:12:16 -030079 struct mantis_ca *ca = en50221->data;
80 struct mantis_pci *mantis = ca->ca_priv;
81
82 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
Manu Abrahamfb6de9c2009-12-04 05:17:46 -030083 udelay(500); /* Wait.. */
84 mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
85 udelay(500);
86 mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
87 msleep(1000);
Manu Abraham2ec9b002009-12-04 05:20:44 -030088 dvb_ca_en50221_camready_irq(&ca->en50221, 0);
Manu Abraham2133ffb2009-12-04 05:12:16 -030089
Manu Abraham50d82602009-12-04 05:06:38 -030090 return 0;
91}
92
Manu Abraham60532402009-12-04 05:11:14 -030093static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -030094{
Manu Abraham2133ffb2009-12-04 05:12:16 -030095 struct mantis_ca *ca = en50221->data;
96 struct mantis_pci *mantis = ca->ca_priv;
97
98 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
99
Manu Abraham50d82602009-12-04 05:06:38 -0300100 return 0;
101}
102
Manu Abraham60532402009-12-04 05:11:14 -0300103static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
Manu Abraham50d82602009-12-04 05:06:38 -0300104{
Manu Abraham2133ffb2009-12-04 05:12:16 -0300105 struct mantis_ca *ca = en50221->data;
106 struct mantis_pci *mantis = ca->ca_priv;
107
108 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
Manu Abraham990f8d12009-12-04 05:18:27 -0300109 mantis_set_direction(mantis, 1); /* Enable TS through CAM */
Manu Abraham2133ffb2009-12-04 05:12:16 -0300110
Manu Abraham50d82602009-12-04 05:06:38 -0300111 return 0;
112}
113
Manu Abraham60532402009-12-04 05:11:14 -0300114static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
Manu Abraham50d82602009-12-04 05:06:38 -0300115{
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300116 struct mantis_ca *ca = en50221->data;
Manu Abraham2133ffb2009-12-04 05:12:16 -0300117 struct mantis_pci *mantis = ca->ca_priv;
118
119 dprintk(verbose, MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300120
Manu Abraham5e2a0c92009-12-04 05:23:17 -0300121 if (ca->slot_state == MODULE_INSERTED) {
122 dprintk(verbose, MANTIS_DEBUG, 1, "CA Module present and ready");
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300123 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
Manu Abraham5e2a0c92009-12-04 05:23:17 -0300124 } else {
125 dprintk(verbose, MANTIS_DEBUG, 1, "CA Module not present or not ready");
126 }
Manu Abraham4e9fbee2009-12-04 05:11:41 -0300127
Manu Abraham50d82602009-12-04 05:06:38 -0300128 return 0;
Manu Abraham50d82602009-12-04 05:06:38 -0300129}
130
Manu Abraham60532402009-12-04 05:11:14 -0300131int mantis_ca_init(struct mantis_pci *mantis)
Manu Abraham50d82602009-12-04 05:06:38 -0300132{
Manu Abraham50d82602009-12-04 05:06:38 -0300133 struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter;
134 struct mantis_ca *ca;
Manu Abraham60532402009-12-04 05:11:14 -0300135 int ca_flags = 0, result;
Manu Abraham50d82602009-12-04 05:06:38 -0300136
Manu Abraham2133ffb2009-12-04 05:12:16 -0300137 dprintk(verbose, MANTIS_DEBUG, 1, "Initializing Mantis CA");
Manu Abraham50d82602009-12-04 05:06:38 -0300138 if (!(ca = kzalloc(sizeof (struct mantis_ca), GFP_KERNEL))) {
139 dprintk(verbose, MANTIS_ERROR, 1, "Out of memory!, exiting ..");
Manu Abraham60532402009-12-04 05:11:14 -0300140 result = -ENOMEM;
141 goto err;
Manu Abraham50d82602009-12-04 05:06:38 -0300142 }
143
144 ca->ca_priv = mantis;
Manu Abraham60532402009-12-04 05:11:14 -0300145 mantis->mantis_ca = ca;
Manu Abrahame26c2b42009-12-04 05:31:45 -0300146 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
Manu Abraham60532402009-12-04 05:11:14 -0300147 /* register CA interface */
148 ca->en50221.owner = THIS_MODULE;
149 ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem;
150 ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem;
151 ca->en50221.read_cam_control = mantis_ca_read_cam_ctl;
152 ca->en50221.write_cam_control = mantis_ca_write_cam_ctl;
153 ca->en50221.slot_reset = mantis_ca_slot_reset;
154 ca->en50221.slot_shutdown = mantis_ca_slot_shutdown;
155 ca->en50221.slot_ts_enable = mantis_ts_control;
156 ca->en50221.poll_slot_status = mantis_slot_status;
157 ca->en50221.data = ca;
158
Manu Abraham99b55b22009-12-04 05:34:44 -0300159 mutex_init(&ca->ca_lock);
160
Manu Abraham60532402009-12-04 05:11:14 -0300161 dprintk(verbose, MANTIS_ERROR, 1, "Registering EN50221 device");
162 if ((result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1)) != 0) {
163 dprintk(verbose, MANTIS_ERROR, 1, "EN50221: Initialization failed");
164 goto err;
Manu Abraham50d82602009-12-04 05:06:38 -0300165 }
Manu Abraham60532402009-12-04 05:11:14 -0300166 dprintk(verbose, MANTIS_ERROR, 1, "Registered EN50221 device");
167 mantis_evmgr_init(ca);
Manu Abraham50d82602009-12-04 05:06:38 -0300168 return 0;
Manu Abraham60532402009-12-04 05:11:14 -0300169err:
170 kfree(ca);
171 return result;
Manu Abraham50d82602009-12-04 05:06:38 -0300172}
173
174void mantis_ca_exit(struct mantis_pci *mantis)
175{
176 struct mantis_ca *ca = mantis->mantis_ca;
Manu Abraham2133ffb2009-12-04 05:12:16 -0300177
178 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis CA exit");
Manu Abraham50d82602009-12-04 05:06:38 -0300179
180 mantis_evmgr_exit(ca);
Manu Abraham60532402009-12-04 05:11:14 -0300181 dprintk(verbose, MANTIS_ERROR, 1, "Unregistering EN50221 device");
182 dvb_ca_en50221_release(&ca->en50221);
Manu Abraham50d82602009-12-04 05:06:38 -0300183
184 kfree(ca);
185}