si2157.c revision e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4
1ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari/* 2ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * Silicon Labs Si2157 silicon tuner driver 3ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 4ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> 5ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 6ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * This program is free software; you can redistribute it and/or modify 7ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * it under the terms of the GNU General Public License as published by 8ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * the Free Software Foundation; either version 2 of the License, or 9ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * (at your option) any later version. 10ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 11ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * This program is distributed in the hope that it will be useful, 12ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * but WITHOUT ANY WARRANTY; without even the implied warranty of 13ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * GNU General Public License for more details. 15ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari */ 16ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari 17930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari#include "si2157_priv.h" 18930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 19930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari/* execute firmware command */ 20930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd) 21930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 22930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 23930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari unsigned long timeout; 24930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 25930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_lock(&s->i2c_mutex); 26930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 27e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari if (cmd->wlen) { 28930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* write cmd and args for firmware */ 29e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari ret = i2c_master_send(s->client, cmd->args, cmd->wlen); 30930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret < 0) { 31930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 32e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari } else if (ret != cmd->wlen) { 33930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -EREMOTEIO; 34930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 35930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 36930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 37930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 38e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari if (cmd->rlen) { 39e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari /* wait cmd execution terminate */ 40e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari #define TIMEOUT 80 41e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari timeout = jiffies + msecs_to_jiffies(TIMEOUT); 42e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari while (!time_after(jiffies, timeout)) { 43e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari ret = i2c_master_recv(s->client, cmd->args, cmd->rlen); 44e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari if (ret < 0) { 45e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari goto err_mutex_unlock; 46e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari } else if (ret != cmd->rlen) { 47e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari ret = -EREMOTEIO; 48e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari goto err_mutex_unlock; 49e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari } 50e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari 51e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari /* firmware ready? */ 52e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari if ((cmd->args[0] >> 7) & 0x01) 53e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari break; 54930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 55930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 56e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", 57e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari __func__, 58e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari jiffies_to_msecs(jiffies) - 59e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari (jiffies_to_msecs(timeout) - TIMEOUT)); 60930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 61e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari if (!((cmd->args[0] >> 7) & 0x01)) { 62e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari ret = -ETIMEDOUT; 63e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari goto err_mutex_unlock; 64e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari } 65930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 66930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 67e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari ret = 0; 68e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari 69930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr_mutex_unlock: 70930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_unlock(&s->i2c_mutex); 71930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 72930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 73930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 74930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 75930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 76930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 77930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 78930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 79930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 80930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_init(struct dvb_frontend *fe) 81930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 82930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 83930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 84930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s:\n", __func__); 85930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 86930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->active = true; 87930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 88930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 89930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 90930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 91930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_sleep(struct dvb_frontend *fe) 92930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 93930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 94a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari int ret; 95a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari struct si2157_cmd cmd; 96930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 97930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s:\n", __func__); 98930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 99930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->active = false; 100930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 101a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari memcpy(cmd.args, "\x13", 1); 102e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 1; 103e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 0; 104a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari ret = si2157_cmd_execute(s, &cmd); 105a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari if (ret) 106a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari goto err; 107a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari 108930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 109a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaarierr: 110a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 111a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari return ret; 112930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 113930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 114930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_set_params(struct dvb_frontend *fe) 115930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 116930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 117930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dtv_frontend_properties *c = &fe->dtv_property_cache; 118930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 119930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_cmd cmd; 120930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 121930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, 122930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari "%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n", 123930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari __func__, c->delivery_system, c->frequency, 124930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari c->bandwidth_hz); 125930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 126930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (!s->active) { 127930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -EAGAIN; 128930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 129930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 130930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 131930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* configure? */ 132930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0xc0; 133930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x00; 134930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[2] = 0x0c; 135930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[3] = 0x00; 136930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[4] = 0x00; 137930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[5] = 0x01; 138930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[6] = 0x01; 139930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[7] = 0x01; 140930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[8] = 0x01; 141930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[9] = 0x01; 142930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[10] = 0x01; 143930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[11] = 0x02; 144930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[12] = 0x00; 145930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[13] = 0x00; 146930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[14] = 0x01; 147e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 15; 148e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 1; 149930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 150930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 151930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 152930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 153930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x02; 154e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 1; 155e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 13; 156930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 157930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 158930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 159930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 160930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x01; 161930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x01; 162e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 2; 163e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 1; 164930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 165930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 166930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 167930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 168930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* set frequency */ 169930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x41; 170930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x00; 171930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[2] = 0x00; 172930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[3] = 0x00; 173930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[4] = (c->frequency >> 0) & 0xff; 174930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[5] = (c->frequency >> 8) & 0xff; 175930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[6] = (c->frequency >> 16) & 0xff; 176930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[7] = (c->frequency >> 24) & 0xff; 177e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 8; 178e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 1; 179930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 180930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 181930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 182930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 183930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 184930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 185930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 186930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 187930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 188930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 189930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic const struct dvb_tuner_ops si2157_tuner_ops = { 190930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .info = { 191930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .name = "Silicon Labs Si2157", 192ae4c8919bb761c7f209fb260a82304a54616da0dAntti Palosaari .frequency_min = 110000000, 193930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .frequency_max = 862000000, 194930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari }, 195930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 196930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .init = si2157_init, 197930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .sleep = si2157_sleep, 198930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .set_params = si2157_set_params, 199930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 200930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 201930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_probe(struct i2c_client *client, 202930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari const struct i2c_device_id *id) 203930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 204930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_config *cfg = client->dev.platform_data; 205930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dvb_frontend *fe = cfg->fe; 206930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s; 207930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_cmd cmd; 208930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 209930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 210930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s = kzalloc(sizeof(struct si2157), GFP_KERNEL); 211930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (!s) { 212930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -ENOMEM; 213930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 214930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 215930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 216930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 217930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->client = client; 218930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->fe = cfg->fe; 219930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_init(&s->i2c_mutex); 220930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 221930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* check if the tuner is there */ 222e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.wlen = 0; 223e6b4380f3ef89601b1a77c327fe3aa7b5500b3f4Antti Palosaari cmd.rlen = 1; 224930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 225930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 226930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 227930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 228930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari fe->tuner_priv = s; 229930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari memcpy(&fe->ops.tuner_ops, &si2157_tuner_ops, 230930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari sizeof(struct dvb_tuner_ops)); 231930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 232930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari i2c_set_clientdata(client, s); 233930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 234930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_info(&s->client->dev, 235930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari "%s: Silicon Labs Si2157 successfully attached\n", 236930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari KBUILD_MODNAME); 237930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 238930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 239930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); 240930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari kfree(s); 241930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 242930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 243930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 244930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 245930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_remove(struct i2c_client *client) 246930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 247930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = i2c_get_clientdata(client); 248930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dvb_frontend *fe = s->fe; 249930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 250930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&client->dev, "%s:\n", __func__); 251930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 252930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); 253930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari fe->tuner_priv = NULL; 254930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari kfree(s); 255930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 256930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 257930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 258930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 259930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic const struct i2c_device_id si2157_id[] = { 260930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari {"si2157", 0}, 261930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari {} 262930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 263930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_DEVICE_TABLE(i2c, si2157_id); 264930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 265930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic struct i2c_driver si2157_driver = { 266930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .driver = { 267930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .owner = THIS_MODULE, 268930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .name = "si2157", 269930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari }, 270930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .probe = si2157_probe, 271930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .remove = si2157_remove, 272930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .id_table = si2157_id, 273930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 274930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 275930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarimodule_i2c_driver(si2157_driver); 276930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 277930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_DESCRIPTION("Silicon Labs Si2157 silicon tuner driver"); 278930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 279930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_LICENSE("GPL"); 280