1df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid/* 2612262a53352af839a14b3395975a3440c95080aStefan Richter * FireDTV driver (formerly known as FireSAT) 3df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * 4612262a53352af839a14b3395975a3440c95080aStefan Richter * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> 5612262a53352af839a14b3395975a3440c95080aStefan Richter * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> 6df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * 7df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * This program is free software; you can redistribute it and/or 8df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * modify it under the terms of the GNU General Public License as 9df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * published by the Free Software Foundation; either version 2 of 10df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid * the License, or (at your option) any later version. 11df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid */ 12df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 13154907957f9391b1af997b57507b16c018cc4995Stefan Richter#include <linux/device.h> 14c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman#include <linux/dvb/ca.h> 15612262a53352af839a14b3395975a3440c95080aStefan Richter#include <linux/fs.h> 16612262a53352af839a14b3395975a3440c95080aStefan Richter#include <linux/module.h> 17612262a53352af839a14b3395975a3440c95080aStefan Richter 18c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman#include <dvbdev.h> 19c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 20a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi#include "firedtv.h" 21612262a53352af839a14b3395975a3440c95080aStefan Richter 22154907957f9391b1af997b57507b16c018cc4995Stefan Richter#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020 23154907957f9391b1af997b57507b16c018cc4995Stefan Richter#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030 24154907957f9391b1af997b57507b16c018cc4995Stefan Richter#define EN50221_TAG_CA_PMT 0x9f8032 25154907957f9391b1af997b57507b16c018cc4995Stefan Richter#define EN50221_TAG_ENTER_MENU 0x9f8022 26154907957f9391b1af997b57507b16c018cc4995Stefan Richter 27154907957f9391b1af997b57507b16c018cc4995Stefan Richterstatic int fdtv_ca_ready(struct firedtv_tuner_status *stat) 28df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 29154907957f9391b1af997b57507b16c018cc4995Stefan Richter return stat->ca_initialization_status == 1 && 30154907957f9391b1af997b57507b16c018cc4995Stefan Richter stat->ca_error_flag == 0 && 31154907957f9391b1af997b57507b16c018cc4995Stefan Richter stat->ca_dvb_flag == 1 && 32154907957f9391b1af997b57507b16c018cc4995Stefan Richter stat->ca_module_present_status == 1; 33df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 34df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 35154907957f9391b1af997b57507b16c018cc4995Stefan Richterstatic int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) 36df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 37df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid int flags = 0; 388ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter 39154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (stat->ca_module_present_status == 1) 40df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid flags |= CA_CI_MODULE_PRESENT; 41154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (stat->ca_initialization_status == 1 && 42154907957f9391b1af997b57507b16c018cc4995Stefan Richter stat->ca_error_flag == 0 && 43154907957f9391b1af997b57507b16c018cc4995Stefan Richter stat->ca_dvb_flag == 1) 44df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid flags |= CA_CI_MODULE_READY; 45df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return flags; 46df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 47df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 48a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_get_caps(void *arg) 49df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 508ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_caps *cap = arg; 518ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter 528ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter cap->slot_num = 1; 538ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter cap->slot_type = CA_CI; 548ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter cap->descr_num = 1; 558ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter cap->descr_type = CA_ECD; 568ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter return 0; 57df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 58df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 59a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) 60df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 61154907957f9391b1af997b57507b16c018cc4995Stefan Richter struct firedtv_tuner_status stat; 628ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_slot_info *slot = arg; 63686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter int err; 64df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 65686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter err = avc_tuner_status(fdtv, &stat); 66686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter if (err) 67686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return err; 68df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 698ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter if (slot->num != 0) 70686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return -EACCES; 718ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter 728ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter slot->type = CA_CI; 73154907957f9391b1af997b57507b16c018cc4995Stefan Richter slot->flags = fdtv_get_ca_flags(&stat); 74df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return 0; 75df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 76df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 77a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) 78df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 798ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_msg *reply = arg; 80df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 81686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return avc_ca_app_info(fdtv, reply->msg, &reply->length); 82df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 83df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 84a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_info(struct firedtv *fdtv, void *arg) 85df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 868ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_msg *reply = arg; 87df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 88686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return avc_ca_info(fdtv, reply->msg, &reply->length); 89df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 90df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 91a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) 92df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 938ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_msg *reply = arg; 94df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 95686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return avc_ca_get_mmi(fdtv, reply->msg, &reply->length); 96df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 97df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 98a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) 99df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 100154907957f9391b1af997b57507b16c018cc4995Stefan Richter struct firedtv_tuner_status stat; 1018ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter int err; 102df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 103a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi switch (fdtv->ca_last_command) { 104154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_APP_INFO_ENQUIRY: 105a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_app_info(fdtv, arg); 106df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 107154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_CA_INFO_ENQUIRY: 108a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_info(fdtv, arg); 109c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman break; 110df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid default: 111686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter err = avc_tuner_status(fdtv, &stat); 112686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter if (err) 113686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter break; 114686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter if (stat.ca_mmi == 1) 115a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_get_mmi(fdtv, arg); 116df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid else { 117154907957f9391b1af997b57507b16c018cc4995Stefan Richter dev_info(fdtv->device, "unhandled CA message 0x%08x\n", 118154907957f9391b1af997b57507b16c018cc4995Stefan Richter fdtv->ca_last_command); 119686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter err = -EACCES; 120df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid } 121df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid } 122a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi fdtv->ca_last_command = 0; 123df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return err; 124df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 125c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 126a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) 127df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 1288ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_msg *msg = arg; 129df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid int data_pos; 1307199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid int data_length; 1317199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid int i; 1327199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid 1337199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid data_pos = 4; 1347199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid if (msg->msg[3] & 0x80) { 1357199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid data_length = 0; 136154907957f9391b1af997b57507b16c018cc4995Stefan Richter for (i = 0; i < (msg->msg[3] & 0x7f); i++) 1377199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid data_length = (data_length << 8) + msg->msg[data_pos++]; 1387199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid } else { 1397199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid data_length = msg->msg[3]; 1407199e523ef71d24cd8030ea454fca00bb52d58f0Henrik Kurelid } 141df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 142686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length); 143df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 144df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 145a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) 146df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 1478ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct ca_msg *msg = arg; 148df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid int err; 149df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 1508ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter /* Do we need a semaphore for this? */ 151a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi fdtv->ca_last_command = 1528ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; 153a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi switch (fdtv->ca_last_command) { 154154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_CA_PMT: 155a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_pmt(fdtv, arg); 156df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 157154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_APP_INFO_ENQUIRY: 1588ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter /* handled in ca_get_msg */ 159c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman err = 0; 160c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman break; 161154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_CA_INFO_ENQUIRY: 1628ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter /* handled in ca_get_msg */ 163c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman err = 0; 164c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman break; 165154907957f9391b1af997b57507b16c018cc4995Stefan Richter case EN50221_TAG_ENTER_MENU: 166a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = avc_ca_enter_menu(fdtv); 167df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 168df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid default: 169154907957f9391b1af997b57507b16c018cc4995Stefan Richter dev_err(fdtv->device, "unhandled CA message 0x%08x\n", 170154907957f9391b1af997b57507b16c018cc4995Stefan Richter fdtv->ca_last_command); 171686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter err = -EACCES; 172c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman } 173df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return err; 174df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid} 175df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 17616ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmannstatic int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg) 177df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 1788ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter struct dvb_device *dvbdev = file->private_data; 179a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi struct firedtv *fdtv = dvbdev->priv; 180154907957f9391b1af997b57507b16c018cc4995Stefan Richter struct firedtv_tuner_status stat; 1818ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter int err; 182df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 183154907957f9391b1af997b57507b16c018cc4995Stefan Richter switch (cmd) { 184df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid case CA_RESET: 185686a9488cd23cce1fa8a6cddde0e7668ae2e74b4Stefan Richter err = avc_ca_reset(fdtv); 186df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 187df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid case CA_GET_CAP: 188a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_get_caps(arg); 189df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 190df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid case CA_GET_SLOT_INFO: 191a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_get_slot_info(fdtv, arg); 192df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 193df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid case CA_GET_MSG: 194a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_get_msg(fdtv, arg); 195df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 196df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid case CA_SEND_MSG: 197a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = fdtv_ca_send_msg(fdtv, arg); 198df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid break; 199c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman default: 200154907957f9391b1af997b57507b16c018cc4995Stefan Richter dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); 201df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid err = -EOPNOTSUPP; 202c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman } 203df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 2048ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter /* FIXME Is this necessary? */ 205154907957f9391b1af997b57507b16c018cc4995Stefan Richter avc_tuner_status(fdtv, &stat); 206df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 207c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman return err; 208c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman} 209c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 210a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) 211df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 212c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman return POLLIN; 213c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman} 214c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 215828c09509b9695271bcbdc53e9fc9a6a737148d2Alexey Dobriyanstatic const struct file_operations fdtv_ca_fops = { 2168ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .owner = THIS_MODULE, 21716ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmann .unlocked_ioctl = dvb_generic_ioctl, 2188ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .open = dvb_generic_open, 2198ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .release = dvb_generic_release, 220a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi .poll = fdtv_ca_io_poll, 2216038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 222c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman}; 223c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 224a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldistatic struct dvb_device fdtv_ca = { 2258ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .users = 1, 2268ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .readers = 1, 2278ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter .writers = 1, 228a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi .fops = &fdtv_ca_fops, 229a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi .kernel_ioctl = fdtv_ca_ioctl, 230c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman}; 231c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 232a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldiint fdtv_ca_register(struct firedtv *fdtv) 233df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 234154907957f9391b1af997b57507b16c018cc4995Stefan Richter struct firedtv_tuner_status stat; 2358ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter int err; 236c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 237154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (avc_tuner_status(fdtv, &stat)) 238df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return -EINVAL; 239df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 240154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (!fdtv_ca_ready(&stat)) 2418ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter return -EFAULT; 2428ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter 243a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, 244a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi &fdtv_ca, fdtv, DVB_DEVICE_CA); 2458ae83cdf3297d7da301af36bdb6ff45bd331c6d0Stefan Richter 246154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (stat.ca_application_info == 0) 247154907957f9391b1af997b57507b16c018cc4995Stefan Richter dev_err(fdtv->device, "CaApplicationInfo is not set\n"); 248154907957f9391b1af997b57507b16c018cc4995Stefan Richter if (stat.ca_date_time_request == 1) 249a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); 250df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid 251df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid return err; 252c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman} 253c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman 254a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldivoid fdtv_ca_release(struct firedtv *fdtv) 255df4846c35247a0d038c5359d502cddd59d04bc40Henrik Kurelid{ 256a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi if (fdtv->cadev) 257a70f81c1c0dac113ac4705e7701e2676e67905cdRambaldi dvb_unregister_device(fdtv->cadev); 258c81c8b68b46752721b0c1addfabb828da27e1489Greg Kroah-Hartman} 259