From patchwork Tue Dec 24 16:17:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Malcolm Priestley X-Patchwork-Id: 3404361 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B92449F169 for ; Tue, 24 Dec 2013 16:17:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C16932055D for ; Tue, 24 Dec 2013 16:17:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E2ECC20557 for ; Tue, 24 Dec 2013 16:17:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752206Ab3LXQRU (ORCPT ); Tue, 24 Dec 2013 11:17:20 -0500 Received: from mail-we0-f181.google.com ([74.125.82.181]:56145 "EHLO mail-we0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751619Ab3LXQRT (ORCPT ); Tue, 24 Dec 2013 11:17:19 -0500 Received: by mail-we0-f181.google.com with SMTP id x55so6162511wes.12 for ; Tue, 24 Dec 2013 08:17:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:subject:from:to:date:content-type:mime-version :content-transfer-encoding; bh=OffyqpN9C+Aq6X7cfa4/H/Xd0fD4yFODavWl8U0p5UE=; b=WQrxiEEN5J4fR5Kpie+JAlx/rAqXPI8feLOgGKXnYbjoTxJ/6ZBmTygUBC4CrD+fUE G17xkiLsEW9Z56ZbdDEOGkvx2qnfZ9EMxUzisUBP40BQMTmukD26oyqJyZVZqC8Xzo9O yvVmZLJ+u65QlVuGmMnRIKCPV2uUKdDbiL3yTnhNsz2WkZ2+os1PV9oPPkwMBfJ7x1UK 0E1uh1SJfqyiUlXRLkmKmJXcSnhGXjiHx3XySkdV1q6kz6a1onmV/qAsuyCY+/RGVDU4 qxKjzJDJPG5+y0W1C3kjUZL9y1l0xYhpNwDFg3lqXC0rqjmeyRiG8b0VU0qMNZk5L2Wo gRaQ== X-Received: by 10.180.108.162 with SMTP id hl2mr23056641wib.56.1387901838096; Tue, 24 Dec 2013 08:17:18 -0800 (PST) Received: from [192.168.1.100] (94.196.117.167.threembb.co.uk. [94.196.117.167]) by mx.google.com with ESMTPSA id po3sm12760103wjc.3.2013.12.24.08.17.16 for (version=SSLv3 cipher=RC4-SHA bits=128/128); Tue, 24 Dec 2013 08:17:17 -0800 (PST) Message-ID: <1387901832.24033.39.camel@canaries32-MCP7A> Subject: [PATCH 1/2] m88rs2000: add m88rs2000_set_carrieroffset From: Malcolm Priestley To: linux-media@vger.kernel.org Date: Tue, 24 Dec 2013 16:17:12 +0000 X-Mailer: Evolution 3.10.1-2ubuntu2 Mime-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Set the carrier offset correctly using the default mclk values. Add function m88rs2000_get_mclk to calculate the mclk value against crystal frequency which will later be used for other functions. Add function m88rs2000_set_carrieroffset to calculate and set the offset value. variable offset becomes a signed value. Register 0x86 is set the appropriate value according to remainder value of frequency % 192857 calculation as shown. Signed-off-by: Malcolm Priestley Cc: stable@vger.kernel.org # v3.9+ --- drivers/media/dvb-frontends/m88rs2000.c | 77 ++++++++++++++++++++++++--------- drivers/media/dvb-frontends/m88rs2000.h | 2 + 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index 4da5272..8091653 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -110,6 +110,52 @@ static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg) return b1[0]; } +static u32 m88rs2000_get_mclk(struct dvb_frontend *fe) +{ + struct m88rs2000_state *state = fe->demodulator_priv; + u32 mclk; + u8 reg; + /* Must not be 0x00 or 0xff */ + reg = m88rs2000_readreg(state, 0x86); + if (!reg || reg == 0xff) + return 0; + + reg /= 2; + reg += 1; + + mclk = (u32)(reg * RS2000_FE_CRYSTAL_KHZ + 28 / 2) / 28; + + return mclk; +} + +static int m88rs2000_set_carrieroffset(struct dvb_frontend *fe, s16 offset) +{ + struct m88rs2000_state *state = fe->demodulator_priv; + u32 mclk; + s32 tmp; + u8 reg; + int ret; + + mclk = m88rs2000_get_mclk(fe); + if (!mclk) + return -EINVAL; + + tmp = (offset * 4096 + (s32)mclk / 2) / (s32)mclk; + if (tmp < 0) + tmp += 4096; + + /* Carrier Offset */ + ret = m88rs2000_writereg(state, 0x9c, (u8)(tmp >> 4)); + + reg = m88rs2000_readreg(state, 0x9d); + reg &= 0xf; + reg |= (u8)(tmp & 0xf) << 4; + + ret |= m88rs2000_writereg(state, 0x9d, reg); + + return ret; +} + static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate) { struct m88rs2000_state *state = fe->demodulator_priv; @@ -540,9 +586,8 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; fe_status_t status; int i, ret = 0; - s32 tmp; u32 tuner_freq; - u16 offset = 0; + s16 offset = 0; u8 reg; state->no_lock_count = 0; @@ -567,26 +612,18 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe) if (ret < 0) return -ENODEV; - offset = tuner_freq - c->frequency; + offset = (s16)((s32)tuner_freq - c->frequency); - /* calculate offset assuming 96000kHz*/ - tmp = offset; - tmp *= 65536; - - tmp = (2 * tmp + 96000) / (2 * 96000); - if (tmp < 0) - tmp += 65536; - - offset = tmp & 0xffff; - - ret = m88rs2000_writereg(state, 0x9a, 0x30); - /* Unknown usually 0xc6 sometimes 0xc1 */ - reg = m88rs2000_readreg(state, 0x86); - ret |= m88rs2000_writereg(state, 0x86, reg); - /* Offset lower nibble always 0 */ - ret |= m88rs2000_writereg(state, 0x9c, (offset >> 8)); - ret |= m88rs2000_writereg(state, 0x9d, offset & 0xf0); + /* default mclk value 96.4285 * 2 * 1000 = 192857 */ + if (((c->frequency % 192857) >= (192857 - 3000)) || + (c->frequency % 192857) <= 3000) + ret = m88rs2000_writereg(state, 0x86, 0xc2); + else + ret = m88rs2000_writereg(state, 0x86, 0xc6); + ret |= m88rs2000_set_carrieroffset(fe, offset); + if (ret < 0) + return -ENODEV; /* Reset Demod */ ret = m88rs2000_tab_set(state, fe_reset); diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h index 14ce31e..0a50ea9 100644 --- a/drivers/media/dvb-frontends/m88rs2000.h +++ b/drivers/media/dvb-frontends/m88rs2000.h @@ -53,6 +53,8 @@ static inline struct dvb_frontend *m88rs2000_attach( } #endif /* CONFIG_DVB_M88RS2000 */ +#define RS2000_FE_CRYSTAL_KHZ 27000 + enum { DEMOD_WRITE = 0x1, WRITE_DELAY = 0x10,