694 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * cxd2099.c: Driver for the Sony CXD2099AR Common Interface Controller4 *5 * Copyright (C) 2010-2013 Digital Devices GmbH6 */7 8#include <linux/slab.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/i2c.h>12#include <linux/regmap.h>13#include <linux/wait.h>14#include <linux/delay.h>15#include <linux/mutex.h>16#include <linux/io.h>17 18#include "cxd2099.h"19 20static int buffermode;21module_param(buffermode, int, 0444);22MODULE_PARM_DESC(buffermode, "Enable CXD2099AR buffer mode (default: disabled)");23 24static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);25 26struct cxd {27 struct dvb_ca_en50221 en;28 29 struct cxd2099_cfg cfg;30 struct i2c_client *client;31 struct regmap *regmap;32 33 u8 regs[0x23];34 u8 lastaddress;35 u8 clk_reg_f;36 u8 clk_reg_b;37 int mode;38 int ready;39 int dr;40 int write_busy;41 int slot_stat;42 43 u8 amem[1024];44 int amem_read;45 46 int cammode;47 struct mutex lock; /* device access lock */48 49 u8 rbuf[1028];50 u8 wbuf[1028];51};52 53static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)54{55 int status = 0;56 57 if (ci->lastaddress != adr)58 status = regmap_write(ci->regmap, 0, adr);59 if (!status) {60 ci->lastaddress = adr;61 62 while (n) {63 int len = n;64 65 if (ci->cfg.max_i2c && len > ci->cfg.max_i2c)66 len = ci->cfg.max_i2c;67 status = regmap_raw_read(ci->regmap, 1, data, len);68 if (status)69 return status;70 data += len;71 n -= len;72 }73 }74 return status;75}76 77static int read_reg(struct cxd *ci, u8 reg, u8 *val)78{79 return read_block(ci, reg, val, 1);80}81 82static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)83{84 int status;85 u8 addr[2] = {address & 0xff, address >> 8};86 87 status = regmap_raw_write(ci->regmap, 2, addr, 2);88 if (!status)89 status = regmap_raw_read(ci->regmap, 3, data, n);90 return status;91}92 93static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)94{95 int status;96 u8 addr[2] = {address & 0xff, address >> 8};97 98 status = regmap_raw_write(ci->regmap, 2, addr, 2);99 if (!status) {100 u8 buf[256];101 102 memcpy(buf, data, n);103 status = regmap_raw_write(ci->regmap, 3, buf, n);104 }105 return status;106}107 108static int read_io(struct cxd *ci, u16 address, unsigned int *val)109{110 int status;111 u8 addr[2] = {address & 0xff, address >> 8};112 113 status = regmap_raw_write(ci->regmap, 2, addr, 2);114 if (!status)115 status = regmap_read(ci->regmap, 3, val);116 return status;117}118 119static int write_io(struct cxd *ci, u16 address, u8 val)120{121 int status;122 u8 addr[2] = {address & 0xff, address >> 8};123 124 status = regmap_raw_write(ci->regmap, 2, addr, 2);125 if (!status)126 status = regmap_write(ci->regmap, 3, val);127 return status;128}129 130static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)131{132 int status = 0;133 unsigned int regval;134 135 if (ci->lastaddress != reg)136 status = regmap_write(ci->regmap, 0, reg);137 if (!status && reg >= 6 && reg <= 8 && mask != 0xff) {138 status = regmap_read(ci->regmap, 1, ®val);139 ci->regs[reg] = regval;140 }141 ci->lastaddress = reg;142 ci->regs[reg] = (ci->regs[reg] & (~mask)) | val;143 if (!status)144 status = regmap_write(ci->regmap, 1, ci->regs[reg]);145 if (reg == 0x20)146 ci->regs[reg] &= 0x7f;147 return status;148}149 150static int write_reg(struct cxd *ci, u8 reg, u8 val)151{152 return write_regm(ci, reg, val, 0xff);153}154 155static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n)156{157 int status = 0;158 u8 *buf = ci->wbuf;159 160 if (ci->lastaddress != adr)161 status = regmap_write(ci->regmap, 0, adr);162 if (status)163 return status;164 165 ci->lastaddress = adr;166 while (n) {167 int len = n;168 169 if (ci->cfg.max_i2c && (len + 1 > ci->cfg.max_i2c))170 len = ci->cfg.max_i2c - 1;171 memcpy(buf, data, len);172 status = regmap_raw_write(ci->regmap, 1, buf, len);173 if (status)174 return status;175 n -= len;176 data += len;177 }178 return status;179}180 181static void set_mode(struct cxd *ci, int mode)182{183 if (mode == ci->mode)184 return;185 186 switch (mode) {187 case 0x00: /* IO mem */188 write_regm(ci, 0x06, 0x00, 0x07);189 break;190 case 0x01: /* ATT mem */191 write_regm(ci, 0x06, 0x02, 0x07);192 break;193 default:194 break;195 }196 ci->mode = mode;197}198 199static void cam_mode(struct cxd *ci, int mode)200{201 u8 dummy;202 203 if (mode == ci->cammode)204 return;205 206 switch (mode) {207 case 0x00:208 write_regm(ci, 0x20, 0x80, 0x80);209 break;210 case 0x01:211 if (!ci->en.read_data)212 return;213 ci->write_busy = 0;214 dev_info(&ci->client->dev, "enable cam buffer mode\n");215 write_reg(ci, 0x0d, 0x00);216 write_reg(ci, 0x0e, 0x01);217 write_regm(ci, 0x08, 0x40, 0x40);218 read_reg(ci, 0x12, &dummy);219 write_regm(ci, 0x08, 0x80, 0x80);220 break;221 default:222 break;223 }224 ci->cammode = mode;225}226 227static int init(struct cxd *ci)228{229 int status;230 231 mutex_lock(&ci->lock);232 ci->mode = -1;233 do {234 status = write_reg(ci, 0x00, 0x00);235 if (status < 0)236 break;237 status = write_reg(ci, 0x01, 0x00);238 if (status < 0)239 break;240 status = write_reg(ci, 0x02, 0x10);241 if (status < 0)242 break;243 status = write_reg(ci, 0x03, 0x00);244 if (status < 0)245 break;246 status = write_reg(ci, 0x05, 0xFF);247 if (status < 0)248 break;249 status = write_reg(ci, 0x06, 0x1F);250 if (status < 0)251 break;252 status = write_reg(ci, 0x07, 0x1F);253 if (status < 0)254 break;255 status = write_reg(ci, 0x08, 0x28);256 if (status < 0)257 break;258 status = write_reg(ci, 0x14, 0x20);259 if (status < 0)260 break;261 262 /* TOSTRT = 8, Mode B (gated clock), falling Edge,263 * Serial, POL=HIGH, MSB264 */265 status = write_reg(ci, 0x0A, 0xA7);266 if (status < 0)267 break;268 269 status = write_reg(ci, 0x0B, 0x33);270 if (status < 0)271 break;272 status = write_reg(ci, 0x0C, 0x33);273 if (status < 0)274 break;275 276 status = write_regm(ci, 0x14, 0x00, 0x0F);277 if (status < 0)278 break;279 status = write_reg(ci, 0x15, ci->clk_reg_b);280 if (status < 0)281 break;282 status = write_regm(ci, 0x16, 0x00, 0x0F);283 if (status < 0)284 break;285 status = write_reg(ci, 0x17, ci->clk_reg_f);286 if (status < 0)287 break;288 289 if (ci->cfg.clock_mode == 2) {290 /* bitrate*2^13/ 72000 */291 u32 reg = ((ci->cfg.bitrate << 13) + 71999) / 72000;292 293 if (ci->cfg.polarity) {294 status = write_reg(ci, 0x09, 0x6f);295 if (status < 0)296 break;297 } else {298 status = write_reg(ci, 0x09, 0x6d);299 if (status < 0)300 break;301 }302 status = write_reg(ci, 0x20, 0x08);303 if (status < 0)304 break;305 status = write_reg(ci, 0x21, (reg >> 8) & 0xff);306 if (status < 0)307 break;308 status = write_reg(ci, 0x22, reg & 0xff);309 if (status < 0)310 break;311 } else if (ci->cfg.clock_mode == 1) {312 if (ci->cfg.polarity) {313 status = write_reg(ci, 0x09, 0x6f); /* D */314 if (status < 0)315 break;316 } else {317 status = write_reg(ci, 0x09, 0x6d);318 if (status < 0)319 break;320 }321 status = write_reg(ci, 0x20, 0x68);322 if (status < 0)323 break;324 status = write_reg(ci, 0x21, 0x00);325 if (status < 0)326 break;327 status = write_reg(ci, 0x22, 0x02);328 if (status < 0)329 break;330 } else {331 if (ci->cfg.polarity) {332 status = write_reg(ci, 0x09, 0x4f); /* C */333 if (status < 0)334 break;335 } else {336 status = write_reg(ci, 0x09, 0x4d);337 if (status < 0)338 break;339 }340 status = write_reg(ci, 0x20, 0x28);341 if (status < 0)342 break;343 status = write_reg(ci, 0x21, 0x00);344 if (status < 0)345 break;346 status = write_reg(ci, 0x22, 0x07);347 if (status < 0)348 break;349 }350 351 status = write_regm(ci, 0x20, 0x80, 0x80);352 if (status < 0)353 break;354 status = write_regm(ci, 0x03, 0x02, 0x02);355 if (status < 0)356 break;357 status = write_reg(ci, 0x01, 0x04);358 if (status < 0)359 break;360 status = write_reg(ci, 0x00, 0x31);361 if (status < 0)362 break;363 364 /* Put TS in bypass */365 status = write_regm(ci, 0x09, 0x08, 0x08);366 if (status < 0)367 break;368 ci->cammode = -1;369 cam_mode(ci, 0);370 } while (0);371 mutex_unlock(&ci->lock);372 373 return 0;374}375 376static int read_attribute_mem(struct dvb_ca_en50221 *ca,377 int slot, int address)378{379 struct cxd *ci = ca->data;380 u8 val;381 382 mutex_lock(&ci->lock);383 set_mode(ci, 1);384 read_pccard(ci, address, &val, 1);385 mutex_unlock(&ci->lock);386 return val;387}388 389static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,390 int address, u8 value)391{392 struct cxd *ci = ca->data;393 394 mutex_lock(&ci->lock);395 set_mode(ci, 1);396 write_pccard(ci, address, &value, 1);397 mutex_unlock(&ci->lock);398 return 0;399}400 401static int read_cam_control(struct dvb_ca_en50221 *ca,402 int slot, u8 address)403{404 struct cxd *ci = ca->data;405 unsigned int val;406 407 mutex_lock(&ci->lock);408 set_mode(ci, 0);409 read_io(ci, address, &val);410 mutex_unlock(&ci->lock);411 return val;412}413 414static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,415 u8 address, u8 value)416{417 struct cxd *ci = ca->data;418 419 mutex_lock(&ci->lock);420 set_mode(ci, 0);421 write_io(ci, address, value);422 mutex_unlock(&ci->lock);423 return 0;424}425 426static int slot_reset(struct dvb_ca_en50221 *ca, int slot)427{428 struct cxd *ci = ca->data;429 430 if (ci->cammode)431 read_data(ca, slot, ci->rbuf, 0);432 433 mutex_lock(&ci->lock);434 cam_mode(ci, 0);435 write_reg(ci, 0x00, 0x21);436 write_reg(ci, 0x06, 0x1F);437 write_reg(ci, 0x00, 0x31);438 write_regm(ci, 0x20, 0x80, 0x80);439 write_reg(ci, 0x03, 0x02);440 ci->ready = 0;441 ci->mode = -1;442 {443 int i;444 445 for (i = 0; i < 100; i++) {446 usleep_range(10000, 11000);447 if (ci->ready)448 break;449 }450 }451 mutex_unlock(&ci->lock);452 return 0;453}454 455static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)456{457 struct cxd *ci = ca->data;458 459 dev_dbg(&ci->client->dev, "%s\n", __func__);460 if (ci->cammode)461 read_data(ca, slot, ci->rbuf, 0);462 mutex_lock(&ci->lock);463 write_reg(ci, 0x00, 0x21);464 write_reg(ci, 0x06, 0x1F);465 msleep(300);466 467 write_regm(ci, 0x09, 0x08, 0x08);468 write_regm(ci, 0x20, 0x80, 0x80); /* Reset CAM Mode */469 write_regm(ci, 0x06, 0x07, 0x07); /* Clear IO Mode */470 471 ci->mode = -1;472 ci->write_busy = 0;473 mutex_unlock(&ci->lock);474 return 0;475}476 477static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)478{479 struct cxd *ci = ca->data;480 481 mutex_lock(&ci->lock);482 write_regm(ci, 0x09, 0x00, 0x08);483 set_mode(ci, 0);484 cam_mode(ci, 1);485 mutex_unlock(&ci->lock);486 return 0;487}488 489static int campoll(struct cxd *ci)490{491 u8 istat;492 493 read_reg(ci, 0x04, &istat);494 if (!istat)495 return 0;496 write_reg(ci, 0x05, istat);497 498 if (istat & 0x40)499 ci->dr = 1;500 if (istat & 0x20)501 ci->write_busy = 0;502 503 if (istat & 2) {504 u8 slotstat;505 506 read_reg(ci, 0x01, &slotstat);507 if (!(2 & slotstat)) {508 if (!ci->slot_stat) {509 ci->slot_stat |=510 DVB_CA_EN50221_POLL_CAM_PRESENT;511 write_regm(ci, 0x03, 0x08, 0x08);512 }513 514 } else {515 if (ci->slot_stat) {516 ci->slot_stat = 0;517 write_regm(ci, 0x03, 0x00, 0x08);518 dev_info(&ci->client->dev, "NO CAM\n");519 ci->ready = 0;520 }521 }522 if ((istat & 8) &&523 ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {524 ci->ready = 1;525 ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;526 }527 }528 return 0;529}530 531static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)532{533 struct cxd *ci = ca->data;534 u8 slotstat;535 536 mutex_lock(&ci->lock);537 campoll(ci);538 read_reg(ci, 0x01, &slotstat);539 mutex_unlock(&ci->lock);540 541 return ci->slot_stat;542}543 544static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)545{546 struct cxd *ci = ca->data;547 u8 msb, lsb;548 u16 len;549 550 mutex_lock(&ci->lock);551 campoll(ci);552 mutex_unlock(&ci->lock);553 554 if (!ci->dr)555 return 0;556 557 mutex_lock(&ci->lock);558 read_reg(ci, 0x0f, &msb);559 read_reg(ci, 0x10, &lsb);560 len = ((u16)msb << 8) | lsb;561 if (len > ecount || len < 2) {562 /* read it anyway or cxd may hang */563 read_block(ci, 0x12, ci->rbuf, len);564 mutex_unlock(&ci->lock);565 return -EIO;566 }567 read_block(ci, 0x12, ebuf, len);568 ci->dr = 0;569 mutex_unlock(&ci->lock);570 return len;571}572 573static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)574{575 struct cxd *ci = ca->data;576 577 if (ci->write_busy)578 return -EAGAIN;579 mutex_lock(&ci->lock);580 write_reg(ci, 0x0d, ecount >> 8);581 write_reg(ci, 0x0e, ecount & 0xff);582 write_block(ci, 0x11, ebuf, ecount);583 ci->write_busy = 1;584 mutex_unlock(&ci->lock);585 return ecount;586}587 588static const struct dvb_ca_en50221 en_templ = {589 .read_attribute_mem = read_attribute_mem,590 .write_attribute_mem = write_attribute_mem,591 .read_cam_control = read_cam_control,592 .write_cam_control = write_cam_control,593 .slot_reset = slot_reset,594 .slot_shutdown = slot_shutdown,595 .slot_ts_enable = slot_ts_enable,596 .poll_slot_status = poll_slot_status,597 .read_data = read_data,598 .write_data = write_data,599};600 601static int cxd2099_probe(struct i2c_client *client)602{603 struct cxd *ci;604 struct cxd2099_cfg *cfg = client->dev.platform_data;605 static const struct regmap_config rm_cfg = {606 .reg_bits = 8,607 .val_bits = 8,608 };609 unsigned int val;610 int ret;611 612 ci = kzalloc(sizeof(*ci), GFP_KERNEL);613 if (!ci) {614 ret = -ENOMEM;615 goto err;616 }617 618 ci->client = client;619 memcpy(&ci->cfg, cfg, sizeof(ci->cfg));620 621 ci->regmap = regmap_init_i2c(client, &rm_cfg);622 if (IS_ERR(ci->regmap)) {623 ret = PTR_ERR(ci->regmap);624 goto err_kfree;625 }626 627 ret = regmap_read(ci->regmap, 0x00, &val);628 if (ret < 0) {629 dev_info(&client->dev, "No CXD2099AR detected at 0x%02x\n",630 client->addr);631 goto err_rmexit;632 }633 634 mutex_init(&ci->lock);635 ci->lastaddress = 0xff;636 ci->clk_reg_b = 0x4a;637 ci->clk_reg_f = 0x1b;638 639 ci->en = en_templ;640 ci->en.data = ci;641 init(ci);642 dev_info(&client->dev, "Attached CXD2099AR at 0x%02x\n", client->addr);643 644 *cfg->en = &ci->en;645 646 if (!buffermode) {647 ci->en.read_data = NULL;648 ci->en.write_data = NULL;649 } else {650 dev_info(&client->dev, "Using CXD2099AR buffer mode");651 }652 653 i2c_set_clientdata(client, ci);654 655 return 0;656 657err_rmexit:658 regmap_exit(ci->regmap);659err_kfree:660 kfree(ci);661err:662 663 return ret;664}665 666static void cxd2099_remove(struct i2c_client *client)667{668 struct cxd *ci = i2c_get_clientdata(client);669 670 regmap_exit(ci->regmap);671 kfree(ci);672}673 674static const struct i2c_device_id cxd2099_id[] = {675 { "cxd2099" },676 {}677};678MODULE_DEVICE_TABLE(i2c, cxd2099_id);679 680static struct i2c_driver cxd2099_driver = {681 .driver = {682 .name = "cxd2099",683 },684 .probe = cxd2099_probe,685 .remove = cxd2099_remove,686 .id_table = cxd2099_id,687};688 689module_i2c_driver(cxd2099_driver);690 691MODULE_DESCRIPTION("Sony CXD2099AR Common Interface controller driver");692MODULE_AUTHOR("Ralph Metzler");693MODULE_LICENSE("GPL v2");694